Internal node links are now cached in a per-node list, instead of being generated...
[blender.git] / source / blender / blenkernel / intern / movieclip.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/blenkernel/intern/movieclip.c
28  *  \ingroup bke
29  */
30
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <fcntl.h>
35
36 #ifndef WIN32
37 #include <unistd.h>
38 #else
39 #include <io.h>
40 #endif
41
42 #include <time.h>
43
44 #ifdef _WIN32
45 #define open _open
46 #define close _close
47 #endif
48
49 #include "MEM_guardedalloc.h"
50
51 #include "DNA_constraint_types.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_space_types.h"
54 #include "DNA_movieclip_types.h"
55 #include "DNA_node_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_view3d_types.h"
59
60 #include "BLI_utildefines.h"
61
62 #include "BLI_blenlib.h"
63 #include "BLI_ghash.h"
64 #include "BLI_math.h"
65 #include "BLI_mempool.h"
66 #include "BLI_threads.h"
67
68 #include "BKE_animsys.h"
69 #include "BKE_constraint.h"
70 #include "BKE_colortools.h"
71 #include "BKE_library.h"
72 #include "BKE_global.h"
73 #include "BKE_main.h"
74 #include "BKE_movieclip.h"
75 #include "BKE_node.h"
76 #include "BKE_image.h"  /* openanim */
77 #include "BKE_tracking.h"
78
79 #include "IMB_colormanagement.h"
80 #include "IMB_imbuf_types.h"
81 #include "IMB_imbuf.h"
82 #include "IMB_moviecache.h"
83
84 /*********************** movieclip buffer loaders *************************/
85
86 static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
87 {
88         char num[FILE_MAX] = {0};
89
90         BLI_strncpy(num, full_name + head_len, numlen + 1);
91
92         return atoi(num);
93 }
94
95 static int rendersize_to_proxy(MovieClipUser *user, int flag)
96 {
97         if ((flag & MCLIP_USE_PROXY) == 0)
98                 return IMB_PROXY_NONE;
99
100         switch (user->render_size) {
101                 case MCLIP_PROXY_RENDER_SIZE_25:
102                         return IMB_PROXY_25;
103
104                 case MCLIP_PROXY_RENDER_SIZE_50:
105                         return IMB_PROXY_50;
106
107                 case MCLIP_PROXY_RENDER_SIZE_75:
108                         return IMB_PROXY_75;
109
110                 case MCLIP_PROXY_RENDER_SIZE_100:
111                         return IMB_PROXY_100;
112
113                 case MCLIP_PROXY_RENDER_SIZE_FULL:
114                         return IMB_PROXY_NONE;
115         }
116
117         return IMB_PROXY_NONE;
118 }
119
120 static int rendersize_to_number(int render_size)
121 {
122         switch (render_size) {
123                 case MCLIP_PROXY_RENDER_SIZE_25:
124                         return 25;
125
126                 case MCLIP_PROXY_RENDER_SIZE_50:
127                         return 50;
128
129                 case MCLIP_PROXY_RENDER_SIZE_75:
130                         return 75;
131
132                 case MCLIP_PROXY_RENDER_SIZE_100:
133                         return 100;
134
135                 case MCLIP_PROXY_RENDER_SIZE_FULL:
136                         return 100;
137         }
138
139         return 100;
140 }
141
142 static int get_timecode(MovieClip *clip, int flag)
143 {
144         if ((flag & MCLIP_USE_PROXY) == 0)
145                 return IMB_TC_NONE;
146
147         return clip->proxy.tc;
148 }
149
150 static void get_sequence_fname(MovieClip *clip, int framenr, char *name)
151 {
152         unsigned short numlen;
153         char head[FILE_MAX], tail[FILE_MAX];
154         int offset;
155
156         BLI_strncpy(name, clip->name, sizeof(clip->name));
157         BLI_stringdec(name, head, tail, &numlen);
158
159         /* movieclips always points to first image from sequence,
160          * autoguess offset for now. could be something smarter in the future
161          */
162         offset = sequence_guess_offset(clip->name, strlen(head), numlen);
163
164         if (numlen)
165                 BLI_stringenc(name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
166         else
167                 BLI_strncpy(name, clip->name, sizeof(clip->name));
168
169         BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id));
170 }
171
172 /* supposed to work with sequences only */
173 static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistorted, int framenr, char *name)
174 {
175         int size = rendersize_to_number(proxy_render_size);
176         char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
177         int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset;
178
179         BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX);
180
181         if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
182                 BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
183         }
184         else {
185                 BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir);
186         }
187
188         if (undistorted)
189                 BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, proxynr);
190         else
191                 BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr);
192
193         BLI_path_abs(name, G.main->name);
194         BLI_path_frame(name, 1, 0);
195
196         strcat(name, ".jpg");
197 }
198
199 static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag)
200 {
201         struct ImBuf *ibuf;
202         char name[FILE_MAX];
203         int loadflag, use_proxy = FALSE;
204         char *colorspace;
205
206         use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
207         if (use_proxy) {
208                 int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
209                 get_proxy_fname(clip, user->render_size, undistort, framenr, name);
210
211                 /* proxies were built using default color space settings */
212                 colorspace = NULL;
213         }
214         else {
215                 get_sequence_fname(clip, framenr, name);
216                 colorspace = clip->colorspace_settings.name;
217         }
218
219         loadflag = IB_rect | IB_multilayer;
220
221         /* read ibuf */
222         ibuf = IMB_loadiffname(name, loadflag, colorspace);
223
224         return ibuf;
225 }
226
227 static void movieclip_open_anim_file(MovieClip *clip)
228 {
229         char str[FILE_MAX];
230
231         if (!clip->anim) {
232                 BLI_strncpy(str, clip->name, FILE_MAX);
233                 BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id));
234
235                 /* FIXME: make several stream accessible in image editor, too */
236                 clip->anim = openanim(str, IB_rect, 0, clip->colorspace_settings.name);
237
238                 if (clip->anim) {
239                         if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
240                                 char dir[FILE_MAX];
241                                 BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
242                                 BLI_path_abs(dir, G.main->name);
243                                 IMB_anim_set_index_dir(clip->anim, dir);
244                         }
245                 }
246         }
247 }
248
249 static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag)
250 {
251         ImBuf *ibuf = NULL;
252         int tc = get_timecode(clip, flag);
253         int proxy = rendersize_to_proxy(user, flag);
254
255         movieclip_open_anim_file(clip);
256
257         if (clip->anim) {
258                 int dur;
259                 int fra;
260
261                 dur = IMB_anim_get_duration(clip->anim, tc);
262                 fra = framenr - clip->start_frame + clip->frame_offset;
263
264                 if (fra < 0)
265                         fra = 0;
266
267                 if (fra > (dur - 1))
268                         fra = dur - 1;
269
270                 ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
271         }
272
273         return ibuf;
274 }
275
276 static void movieclip_calc_length(MovieClip *clip)
277 {
278         if (clip->source == MCLIP_SRC_MOVIE) {
279                 movieclip_open_anim_file(clip);
280
281                 if (clip->anim) {
282                         clip->len = IMB_anim_get_duration(clip->anim, clip->proxy.tc);
283                 }
284         }
285         else if (clip->source == MCLIP_SRC_SEQUENCE) {
286                 int framenr = 1;
287                 unsigned short numlen;
288                 char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
289
290                 BLI_stringdec(clip->name, head, tail, &numlen);
291
292                 if (numlen == 0) {
293                         /* there's no number group in file name, assume it's single framed sequence */
294                         clip->len = framenr + 1;
295                 }
296                 else {
297                         for (;;) {
298                                 get_sequence_fname(clip, framenr, name);
299
300                                 if (!BLI_exists(name)) {
301                                         clip->len = framenr;
302                                         break;
303                                 }
304
305                                 framenr++;
306                         }
307                 }
308         }
309 }
310
311 /*********************** image buffer cache *************************/
312
313 typedef struct MovieClipCache {
314         /* regular movie cache */
315         struct MovieCache *moviecache;
316
317         /* cached postprocessed shot */
318         struct {
319                 ImBuf *ibuf;
320                 int framenr;
321                 int flag;
322
323                 /* cache for undistorted shot */
324                 float principal[2];
325                 float k1, k2, k3;
326                 short undistortion_used;
327
328                 int proxy;
329                 short render_flag;
330         } postprocessed;
331
332         /* cache for stable shot */
333         struct {
334                 ImBuf *reference_ibuf;
335
336                 ImBuf *ibuf;
337                 int framenr;
338                 int postprocess_flag;
339
340                 float loc[2], scale, angle, aspect;
341                 int proxy, filter;
342                 short render_flag;
343         } stabilized;
344 } MovieClipCache;
345
346 typedef struct MovieClipImBufCacheKey {
347         int framenr;
348         int proxy;
349         short render_flag;
350 } MovieClipImBufCacheKey;
351
352 typedef struct MovieClipCachePriorityData {
353         int framenr;
354 } MovieClipCachePriorityData;
355
356 static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
357 {
358         MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey;
359
360         *framenr = key->framenr;
361         *proxy = key->proxy;
362         *render_flags = key->render_flag;
363 }
364
365 static unsigned int moviecache_hashhash(const void *keyv)
366 {
367         MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)keyv;
368         int rval = key->framenr;
369
370         return rval;
371 }
372
373 static int moviecache_hashcmp(const void *av, const void *bv)
374 {
375         const MovieClipImBufCacheKey *a = (MovieClipImBufCacheKey *)av;
376         const MovieClipImBufCacheKey *b = (MovieClipImBufCacheKey *)bv;
377
378         if (a->framenr < b->framenr)
379                 return -1;
380         else if (a->framenr > b->framenr)
381                 return 1;
382
383         if (a->proxy < b->proxy)
384                 return -1;
385         else if (a->proxy > b->proxy)
386                 return 1;
387
388         if (a->render_flag < b->render_flag)
389                 return -1;
390         else if (a->render_flag > b->render_flag)
391                 return 1;
392
393         return 0;
394 }
395
396 static void *moviecache_getprioritydata(void *key_v)
397 {
398         MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *) key_v;
399         MovieClipCachePriorityData *priority_data;
400
401         priority_data = MEM_callocN(sizeof(priority_data), "movie cache clip priority data");
402         priority_data->framenr = key->framenr;
403
404         return priority_data;
405 }
406
407 static int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v)
408 {
409         MovieClipImBufCacheKey *last_userkey = (MovieClipImBufCacheKey *) last_userkey_v;
410         MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v;
411
412         return -abs(last_userkey->framenr - priority_data->framenr);
413 }
414
415 static void moviecache_prioritydeleter(void *priority_data_v)
416 {
417         MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v;
418
419         MEM_freeN(priority_data);
420 }
421
422 static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
423 {
424         if (clip->cache) {
425                 MovieClipImBufCacheKey key;
426
427                 key.framenr = user->framenr;
428
429                 if (flag & MCLIP_USE_PROXY) {
430                         key.proxy = rendersize_to_proxy(user, flag);
431                         key.render_flag = user->render_flag;
432                 }
433                 else {
434                         key.proxy = IMB_PROXY_NONE;
435                         key.render_flag = 0;
436                 }
437
438                 return IMB_moviecache_get(clip->cache->moviecache, &key);
439         }
440
441         return NULL;
442 }
443
444 static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag)
445 {
446         MovieClipImBufCacheKey key;
447
448         if (!clip->cache) {
449                 struct MovieCache *moviecache;
450
451                 // char cache_name[64];
452                 // BLI_snprintf(cache_name, sizeof(cache_name), "movie %s", clip->id.name);
453
454                 clip->cache = MEM_callocN(sizeof(MovieClipCache), "movieClipCache");
455
456                 moviecache = IMB_moviecache_create("movieclip", sizeof(MovieClipImBufCacheKey), moviecache_hashhash, moviecache_hashcmp);
457
458                 IMB_moviecache_set_getdata_callback(moviecache, moviecache_keydata);
459                 IMB_moviecache_set_priority_callback(moviecache, moviecache_getprioritydata, moviecache_getitempriority,
460                                                      moviecache_prioritydeleter);
461
462                 clip->cache->moviecache = moviecache;
463         }
464
465         key.framenr = user->framenr;
466
467         if (flag & MCLIP_USE_PROXY) {
468                 key.proxy = rendersize_to_proxy(user, flag);
469                 key.render_flag = user->render_flag;
470         }
471         else {
472                 key.proxy = IMB_PROXY_NONE;
473                 key.render_flag = 0;
474         }
475
476         IMB_moviecache_put(clip->cache->moviecache, &key, ibuf);
477 }
478
479 /*********************** common functions *************************/
480
481 /* only image block itself */
482 static MovieClip *movieclip_alloc(const char *name)
483 {
484         MovieClip *clip;
485
486         clip = BKE_libblock_alloc(&G.main->movieclip, ID_MC, name);
487
488         clip->aspx = clip->aspy = 1.0f;
489
490         BKE_tracking_settings_init(&clip->tracking);
491         BKE_color_managed_colorspace_settings_init(&clip->colorspace_settings);
492
493         clip->proxy.build_size_flag = IMB_PROXY_25;
494         clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN |
495                                     IMB_TC_FREE_RUN |
496                                     IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN |
497                                     IMB_TC_RECORD_RUN_NO_GAPS;
498         clip->proxy.quality = 90;
499
500         clip->start_frame = 1;
501         clip->frame_offset = 0;
502
503         return clip;
504 }
505
506 static void movieclip_load_get_szie(MovieClip *clip)
507 {
508         int width, height;
509         MovieClipUser user = {0};
510
511         user.framenr = 1;
512         BKE_movieclip_get_size(clip, &user, &width, &height);
513
514         if (width && height) {
515                 clip->tracking.camera.principal[0] = ((float)width) / 2.0f;
516                 clip->tracking.camera.principal[1] = ((float)height) / 2.0f;
517         }
518         else {
519                 clip->lastsize[0] = clip->lastsize[1] = IMG_SIZE_FALLBACK;
520         }
521 }
522
523 /* checks if image was already loaded, then returns same image
524  * otherwise creates new.
525  * does not load ibuf itself
526  * pass on optional frame for #name images */
527 MovieClip *BKE_movieclip_file_add(const char *name)
528 {
529         MovieClip *clip;
530         int file, len;
531         const char *libname;
532         char str[FILE_MAX], strtest[FILE_MAX];
533
534         BLI_strncpy(str, name, sizeof(str));
535         BLI_path_abs(str, G.main->name);
536
537         /* exists? */
538         file = BLI_open(str, O_BINARY | O_RDONLY, 0);
539         if (file == -1)
540                 return NULL;
541         close(file);
542
543         /* ** first search an identical clip ** */
544         for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
545                 BLI_strncpy(strtest, clip->name, sizeof(clip->name));
546                 BLI_path_abs(strtest, G.main->name);
547
548                 if (strcmp(strtest, str) == 0) {
549                         BLI_strncpy(clip->name, name, sizeof(clip->name));  /* for stringcode */
550                         clip->id.us++;  /* officially should not, it doesn't link here! */
551
552                         return clip;
553                 }
554         }
555
556         /* ** add new movieclip ** */
557
558         /* create a short library name */
559         len = strlen(name);
560
561         while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
562                 len--;
563         libname = name + len;
564
565         clip = movieclip_alloc(libname);
566         BLI_strncpy(clip->name, name, sizeof(clip->name));
567
568         if (BLI_testextensie_array(name, imb_ext_movie))
569                 clip->source = MCLIP_SRC_MOVIE;
570         else
571                 clip->source = MCLIP_SRC_SEQUENCE;
572
573         movieclip_load_get_szie(clip);
574         if (clip->lastsize[0]) {
575                 int width = clip->lastsize[0];
576
577                 clip->tracking.camera.focal = 24.0f * width / clip->tracking.camera.sensor_width;
578         }
579
580         movieclip_calc_length(clip);
581
582         return clip;
583 }
584
585 static void real_ibuf_size(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int *width, int *height)
586 {
587         *width = ibuf->x;
588         *height = ibuf->y;
589
590         if (clip->flag & MCLIP_USE_PROXY) {
591                 switch (user->render_size) {
592                         case MCLIP_PROXY_RENDER_SIZE_25:
593                                 (*width) *= 4;
594                                 (*height) *= 4;
595                                 break;
596
597                         case MCLIP_PROXY_RENDER_SIZE_50:
598                                 (*width) *= 2.0f;
599                                 (*height) *= 2.0f;
600                                 break;
601
602                         case MCLIP_PROXY_RENDER_SIZE_75:
603                                 *width = ((float)*width) * 4.0f / 3.0f;
604                                 *height = ((float)*height) * 4.0f / 3.0f;
605                                 break;
606                 }
607         }
608 }
609
610 static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf)
611 {
612         ImBuf *undistibuf;
613
614         if (distortion)
615                 undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1);
616         else
617                 undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
618
619         IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y);
620
621         return undistibuf;
622 }
623
624 static int need_undistortion_postprocess(MovieClipUser *user)
625 {
626         int result = 0;
627
628         /* only full undistorted render can be used as on-fly undistorting image */
629         result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) &&
630                   (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
631
632         return result;
633 }
634
635 static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag)
636 {
637         int result = postprocess_flag;
638
639         result |= need_undistortion_postprocess(user);
640
641         return result;
642 }
643
644 static int check_undistortion_cache_flags(MovieClip *clip)
645 {
646         MovieClipCache *cache = clip->cache;
647         MovieTrackingCamera *camera = &clip->tracking.camera;
648
649         /* check for distortion model changes */
650         if (!equals_v2v2(camera->principal, cache->postprocessed.principal))
651                 return FALSE;
652
653         if (!equals_v3v3(&camera->k1, &cache->postprocessed.k1))
654                 return FALSE;
655
656         return TRUE;
657 }
658
659 static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag)
660 {
661         MovieClipCache *cache = clip->cache;
662         int framenr = user->framenr;
663         short proxy = IMB_PROXY_NONE;
664         int render_flag = 0;
665
666         if (flag & MCLIP_USE_PROXY) {
667                 proxy = rendersize_to_proxy(user, flag);
668                 render_flag = user->render_flag;
669         }
670
671         /* no cache or no cached postprocessed image */
672         if (!clip->cache || !clip->cache->postprocessed.ibuf)
673                 return NULL;
674
675         /* postprocessing happened for other frame */
676         if (cache->postprocessed.framenr != framenr)
677                 return NULL;
678
679         /* cached ibuf used different proxy settings */
680         if (cache->postprocessed.render_flag != render_flag || cache->postprocessed.proxy != proxy)
681                 return NULL;
682
683         if (cache->postprocessed.flag != postprocess_flag)
684                 return NULL;
685
686         if (need_undistortion_postprocess(user)) {
687                 if (!check_undistortion_cache_flags(clip))
688                         return NULL;
689         }
690         else if (cache->postprocessed.undistortion_used)
691                 return NULL;
692
693         IMB_refImBuf(cache->postprocessed.ibuf);
694
695         return cache->postprocessed.ibuf;
696 }
697
698 static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf,
699                                                int flag, int postprocess_flag)
700 {
701         MovieClipCache *cache = clip->cache;
702         MovieTrackingCamera *camera = &clip->tracking.camera;
703         ImBuf *postproc_ibuf = NULL;
704
705         cache->postprocessed.framenr = user->framenr;
706         cache->postprocessed.flag = postprocess_flag;
707
708         if (flag & MCLIP_USE_PROXY) {
709                 cache->postprocessed.proxy = rendersize_to_proxy(user, flag);
710                 cache->postprocessed.render_flag = user->render_flag;
711         }
712         else {
713                 cache->postprocessed.proxy = IMB_PROXY_NONE;
714                 cache->postprocessed.render_flag = 0;
715         }
716
717         if (need_undistortion_postprocess(user)) {
718                 copy_v2_v2(cache->postprocessed.principal, camera->principal);
719                 copy_v3_v3(&cache->postprocessed.k1, &camera->k1);
720                 cache->postprocessed.undistortion_used = TRUE;
721                 postproc_ibuf = get_undistorted_ibuf(clip, NULL, ibuf);
722         }
723         else {
724                 cache->postprocessed.undistortion_used = FALSE;
725         }
726
727         if (postprocess_flag) {
728                 int disable_red   = postprocess_flag & MOVIECLIP_DISABLE_RED,
729                     disable_green = postprocess_flag & MOVIECLIP_DISABLE_GREEN,
730                     disable_blue  = postprocess_flag & MOVIECLIP_DISABLE_BLUE,
731                     grayscale     = postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE;
732
733                 if (!postproc_ibuf)
734                         postproc_ibuf = IMB_dupImBuf(ibuf);
735
736                 if (disable_red || disable_green || disable_blue || grayscale)
737                         BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
738         }
739
740         IMB_refImBuf(postproc_ibuf);
741
742         if (cache->postprocessed.ibuf)
743                 IMB_freeImBuf(cache->postprocessed.ibuf);
744
745         cache->postprocessed.ibuf = postproc_ibuf;
746
747         return postproc_ibuf;
748 }
749
750 static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int flag,
751                                                int postprocess_flag, int cache_flag)
752 {
753         ImBuf *ibuf = NULL;
754         int framenr = user->framenr, need_postprocess = FALSE;
755
756         /* cache isn't threadsafe itself and also loading of movies
757          * can't happen from concurent threads that's why we use lock here */
758         BLI_lock_thread(LOCK_MOVIECLIP);
759
760         /* try to obtain cached postprocessed frame first */
761         if (need_postprocessed_frame(user, postprocess_flag)) {
762                 ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag);
763
764                 if (!ibuf)
765                         need_postprocess = TRUE;
766         }
767
768         if (!ibuf)
769                 ibuf = get_imbuf_cache(clip, user, flag);
770
771         if (!ibuf) {
772                 int use_sequence = FALSE;
773
774                 /* undistorted proxies for movies should be read as image sequence */
775                 use_sequence = (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) &&
776                                (user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL);
777
778                 if (clip->source == MCLIP_SRC_SEQUENCE || use_sequence) {
779                         ibuf = movieclip_load_sequence_file(clip, user, framenr, flag);
780                 }
781                 else {
782                         ibuf = movieclip_load_movie_file(clip, user, framenr, flag);
783                 }
784
785                 if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0)
786                         put_imbuf_cache(clip, user, ibuf, flag);
787         }
788
789         if (ibuf) {
790                 clip->lastframe = framenr;
791                 real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
792
793                 /* postprocess frame and put to cache */
794                 if (need_postprocess) {
795                         ImBuf *tmpibuf = ibuf;
796                         ibuf = put_postprocessed_frame_to_cache(clip, user, tmpibuf, flag, postprocess_flag);
797                         IMB_freeImBuf(tmpibuf);
798                 }
799         }
800
801         BLI_unlock_thread(LOCK_MOVIECLIP);
802
803         return ibuf;
804 }
805
806 ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user)
807 {
808         return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0);
809 }
810
811 ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag)
812 {
813         return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag);
814 }
815
816 ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int postprocess_flag)
817 {
818         return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0);
819 }
820
821 static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, ImBuf *reference_ibuf,
822                                       int framenr, int postprocess_flag)
823 {
824         MovieClipCache *cache = clip->cache;
825         MovieTracking *tracking = &clip->tracking;
826         ImBuf *stableibuf;
827         float tloc[2], tscale, tangle;
828         short proxy = IMB_PROXY_NONE;
829         int render_flag = 0;
830         int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
831
832         if (clip->flag & MCLIP_USE_PROXY) {
833                 proxy = rendersize_to_proxy(user, clip->flag);
834                 render_flag = user->render_flag;
835         }
836
837         /* there's no cached frame or it was calculated for another frame */
838         if (!cache->stabilized.ibuf || cache->stabilized.framenr != framenr)
839                 return NULL;
840
841         if (cache->stabilized.reference_ibuf != reference_ibuf)
842                 return NULL;
843
844         /* cached ibuf used different proxy settings */
845         if (cache->stabilized.render_flag != render_flag || cache->stabilized.proxy != proxy)
846                 return NULL;
847
848         if (cache->stabilized.postprocess_flag != postprocess_flag)
849                 return NULL;
850
851         /* stabilization also depends on pixel aspect ratio */
852         if (cache->stabilized.aspect != tracking->camera.pixel_aspect)
853                 return NULL;
854
855         if (cache->stabilized.filter != tracking->stabilization.filter)
856                 return NULL;
857
858         stableibuf = cache->stabilized.ibuf;
859
860         BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
861
862         /* check for stabilization parameters */
863         if (tscale != cache->stabilized.scale ||
864             tangle != cache->stabilized.angle ||
865             !equals_v2v2(tloc, cache->stabilized.loc))
866         {
867                 return NULL;
868         }
869
870         IMB_refImBuf(stableibuf);
871
872         return stableibuf;
873 }
874
875 static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf,
876                                             int framenr, int postprocess_flag)
877 {
878         MovieClipCache *cache = clip->cache;
879         MovieTracking *tracking = &clip->tracking;
880         ImBuf *stableibuf;
881         float tloc[2], tscale, tangle;
882         int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
883
884         stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, clip_framenr, ibuf, tloc, &tscale, &tangle);
885
886         copy_v2_v2(cache->stabilized.loc, tloc);
887
888         cache->stabilized.scale = tscale;
889         cache->stabilized.angle = tangle;
890         cache->stabilized.framenr = framenr;
891         cache->stabilized.aspect = tracking->camera.pixel_aspect;
892         cache->stabilized.filter = tracking->stabilization.filter;
893
894         if (clip->flag & MCLIP_USE_PROXY) {
895                 cache->stabilized.proxy = rendersize_to_proxy(user, clip->flag);
896                 cache->stabilized.render_flag = user->render_flag;
897         }
898         else {
899                 cache->stabilized.proxy = IMB_PROXY_NONE;
900                 cache->stabilized.render_flag = 0;
901         }
902
903         cache->stabilized.postprocess_flag = postprocess_flag;
904
905         if (cache->stabilized.ibuf)
906                 IMB_freeImBuf(cache->stabilized.ibuf);
907
908         cache->stabilized.ibuf = stableibuf;
909
910         IMB_refImBuf(stableibuf);
911
912         return stableibuf;
913 }
914
915 ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle,
916                                      int postprocess_flag)
917 {
918         ImBuf *ibuf, *stableibuf = NULL;
919         int framenr = user->framenr;
920
921         ibuf = BKE_movieclip_get_postprocessed_ibuf(clip, user, postprocess_flag);
922
923         if (!ibuf)
924                 return NULL;
925
926         if (clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
927                 MovieClipCache *cache = clip->cache;
928
929                 stableibuf = get_stable_cached_frame(clip, user, ibuf, framenr, postprocess_flag);
930
931                 if (!stableibuf)
932                         stableibuf = put_stabilized_frame_to_cache(clip, user, ibuf, framenr, postprocess_flag);
933
934                 if (loc)
935                         copy_v2_v2(loc, cache->stabilized.loc);
936
937                 if (scale)
938                         *scale = cache->stabilized.scale;
939
940                 if (angle)
941                         *angle = cache->stabilized.angle;
942         }
943         else {
944                 if (loc)
945                         zero_v2(loc);
946
947                 if (scale)
948                         *scale = 1.0f;
949
950                 if (angle)
951                         *angle = 0.0f;
952
953                 stableibuf = ibuf;
954         }
955
956         if (stableibuf != ibuf) {
957                 IMB_freeImBuf(ibuf);
958                 ibuf = stableibuf;
959         }
960
961         return ibuf;
962
963 }
964
965 int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
966 {
967         ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
968
969         if (ibuf) {
970                 IMB_freeImBuf(ibuf);
971                 return TRUE;
972         }
973
974         return FALSE;
975 }
976
977 void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
978 {
979 #if 0
980         /* originally was needed to support image sequences with different image dimensions,
981          * which might be useful for such things as reconstruction of unordered image sequence,
982          * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded
983          * cache lookups and even unwanted non-proxied files loading when doing mask parenting,
984          * so let's disable this for now and assume image sequence consists of images with
985          * equal sizes (sergey)
986          */
987         if (user->framenr == clip->lastframe) {
988 #endif
989         if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
990                 *width = clip->lastsize[0];
991                 *height = clip->lastsize[1];
992         }
993         else {
994                 ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
995
996                 if (ibuf && ibuf->x && ibuf->y) {
997                         real_ibuf_size(clip, user, ibuf, width, height);
998                 }
999                 else {
1000                         *width = clip->lastsize[0];
1001                         *height = clip->lastsize[1];
1002                 }
1003
1004                 if (ibuf)
1005                         IMB_freeImBuf(ibuf);
1006         }
1007 }
1008 void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2])
1009 {
1010         int width, height;
1011         BKE_movieclip_get_size(clip, user, &width, &height);
1012
1013         size[0] = (float)width;
1014         size[1] = (float)height;
1015 }
1016
1017 int BKE_movieclip_get_duration(MovieClip *clip)
1018 {
1019         if (!clip->len) {
1020                 movieclip_calc_length(clip);
1021         }
1022
1023         return clip->len;
1024 }
1025
1026 void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy)
1027 {
1028         *aspx = 1.0;
1029
1030         /* x is always 1 */
1031         *aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
1032 }
1033
1034 /* get segments of cached frames. useful for debugging cache policies */
1035 void BKE_movieclip_get_cache_segments(MovieClip *clip, MovieClipUser *user, int *totseg_r, int **points_r)
1036 {
1037         *totseg_r = 0;
1038         *points_r = NULL;
1039
1040         if (clip->cache) {
1041                 int proxy = rendersize_to_proxy(user, clip->flag);
1042
1043                 IMB_moviecache_get_cache_segments(clip->cache->moviecache, proxy, user->render_flag, totseg_r, points_r);
1044         }
1045 }
1046
1047 void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
1048 {
1049         /* TODO: clamp framenr here? */
1050
1051         iuser->framenr = framenr;
1052 }
1053
1054 static void free_buffers(MovieClip *clip)
1055 {
1056         if (clip->cache) {
1057                 IMB_moviecache_free(clip->cache->moviecache);
1058
1059                 if (clip->cache->postprocessed.ibuf)
1060                         IMB_freeImBuf(clip->cache->postprocessed.ibuf);
1061
1062                 if (clip->cache->stabilized.ibuf)
1063                         IMB_freeImBuf(clip->cache->stabilized.ibuf);
1064
1065                 MEM_freeN(clip->cache);
1066                 clip->cache = NULL;
1067         }
1068
1069         if (clip->anim) {
1070                 IMB_free_anim(clip->anim);
1071                 clip->anim = NULL;
1072         }
1073
1074         BKE_free_animdata((ID *) clip);
1075 }
1076
1077 void BKE_movieclip_reload(MovieClip *clip)
1078 {
1079         /* clear cache */
1080         free_buffers(clip);
1081
1082         clip->tracking.stabilization.ok = FALSE;
1083
1084         /* update clip source */
1085         if (BLI_testextensie_array(clip->name, imb_ext_movie))
1086                 clip->source = MCLIP_SRC_MOVIE;
1087         else
1088                 clip->source = MCLIP_SRC_SEQUENCE;
1089
1090         clip->lastsize[0] = clip->lastsize[1] = 0;
1091         movieclip_load_get_szie(clip);
1092
1093         movieclip_calc_length(clip);
1094
1095         /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded
1096          * (node trees which are not currently visible wouldn't be refreshed)
1097          */
1098         {
1099                 Scene *scene;
1100                 for (scene = G.main->scene.first; scene; scene = scene->id.next) {
1101                         if (scene->nodetree) {
1102                                 nodeUpdateID(scene->nodetree, &clip->id);
1103                         }
1104                 }
1105         }
1106 }
1107
1108 void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
1109 {
1110         if (scopes->ok)
1111                 return;
1112
1113         if (scopes->track_preview) {
1114                 IMB_freeImBuf(scopes->track_preview);
1115                 scopes->track_preview = NULL;
1116         }
1117
1118         if (scopes->track_search) {
1119                 IMB_freeImBuf(scopes->track_search);
1120                 scopes->track_search = NULL;
1121         }
1122
1123         scopes->marker = NULL;
1124         scopes->track = NULL;
1125         scopes->track_locked = TRUE;
1126
1127         if (clip) {
1128                 MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
1129
1130                 if (act_track) {
1131                         MovieTrackingTrack *track = act_track;
1132                         int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
1133                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1134
1135                         scopes->marker = marker;
1136                         scopes->track = track;
1137
1138                         if (marker->flag & MARKER_DISABLED) {
1139                                 scopes->track_disabled = TRUE;
1140                         }
1141                         else {
1142                                 ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1143
1144                                 scopes->track_disabled = FALSE;
1145
1146                                 if (ibuf && (ibuf->rect || ibuf->rect_float)) {
1147                                         ImBuf *search_ibuf;
1148                                         MovieTrackingMarker undist_marker = *marker;
1149
1150                                         if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1151                                                 int width, height;
1152                                                 float aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1153
1154                                                 BKE_movieclip_get_size(clip, user, &width, &height);
1155
1156                                                 undist_marker.pos[0] *= width;
1157                                                 undist_marker.pos[1] *= height * aspy;
1158
1159                                                 BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);
1160
1161                                                 undist_marker.pos[0] /= width;
1162                                                 undist_marker.pos[1] /= height * aspy;
1163                                         }
1164
1165                                         search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE);
1166
1167                                         if (!search_ibuf->rect_float) {
1168                                                 /* sampling happens in float buffer */
1169                                                 IMB_float_from_rect(search_ibuf);
1170                                         }
1171
1172                                         scopes->undist_marker = undist_marker;
1173                                         scopes->track_search = search_ibuf;
1174
1175                                         scopes->frame_width = ibuf->x;
1176                                         scopes->frame_height = ibuf->y;
1177
1178                                         scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
1179                                 }
1180
1181                                 IMB_freeImBuf(ibuf);
1182                         }
1183
1184                         if ((track->flag & TRACK_LOCKED) == 0) {
1185                                 float pat_min[2], pat_max[2];
1186
1187                                 scopes->track_locked = FALSE;
1188
1189                                 /* XXX: would work fine with non-transformed patterns, but would likely fail
1190                                  *      with transformed patterns, but that would be easier to debug when
1191                                  *      we'll have real pattern sampling (at least to test) */
1192                                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1193
1194                                 scopes->slide_scale[0] = pat_max[0] - pat_min[0];
1195                                 scopes->slide_scale[1] = pat_max[1] - pat_min[1];
1196                         }
1197                 }
1198         }
1199
1200         scopes->framenr = user->framenr;
1201         scopes->ok = TRUE;
1202 }
1203
1204 static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
1205 {
1206         char name[FILE_MAX];
1207         int quality, rectx, recty;
1208         int size = rendersize_to_number(proxy_render_size);
1209         ImBuf *scaleibuf;
1210
1211         get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);
1212
1213         rectx = ibuf->x * size / 100.0f;
1214         recty = ibuf->y * size / 100.0f;
1215
1216         scaleibuf = IMB_dupImBuf(ibuf);
1217
1218         IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
1219
1220         quality = clip->proxy.quality;
1221         scaleibuf->ftype = JPG | quality;
1222
1223         /* unsupported feature only confuses other s/w */
1224         if (scaleibuf->planes == 32)
1225                 scaleibuf->planes = 24;
1226
1227         BLI_lock_thread(LOCK_MOVIECLIP);
1228
1229         BLI_make_existing_file(name);
1230         if (IMB_saveiff(scaleibuf, name, IB_rect) == 0)
1231                 perror(name);
1232
1233         BLI_unlock_thread(LOCK_MOVIECLIP);
1234
1235         IMB_freeImBuf(scaleibuf);
1236 }
1237
1238 void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
1239                                      int cfra, int *build_sizes, int build_count, int undistorted)
1240 {
1241         ImBuf *ibuf;
1242         MovieClipUser user;
1243
1244         user.framenr = cfra;
1245         user.render_flag = 0;
1246         user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
1247
1248         ibuf = BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP);
1249
1250         if (ibuf) {
1251                 ImBuf *tmpibuf = ibuf;
1252                 int i;
1253
1254                 if (undistorted)
1255                         tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
1256
1257                 for (i = 0; i < build_count; i++)
1258                         movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
1259
1260                 IMB_freeImBuf(ibuf);
1261
1262                 if (tmpibuf != ibuf)
1263                         IMB_freeImBuf(tmpibuf);
1264         }
1265 }
1266
1267 void BKE_movieclip_free(MovieClip *clip)
1268 {
1269         free_buffers(clip);
1270
1271         BKE_tracking_free(&clip->tracking);
1272 }
1273
1274 void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
1275 {
1276         bScreen *scr;
1277         ScrArea *area;
1278         SpaceLink *sl;
1279         Scene *sce;
1280         Object *ob;
1281
1282         for (scr = bmain->screen.first; scr; scr = scr->id.next) {
1283                 for (area = scr->areabase.first; area; area = area->next) {
1284                         for (sl = area->spacedata.first; sl; sl = sl->next) {
1285                                 if (sl->spacetype == SPACE_CLIP) {
1286                                         SpaceClip *sc = (SpaceClip *) sl;
1287
1288                                         if (sc->clip == clip)
1289                                                 sc->clip = NULL;
1290                                 }
1291                                 else if (sl->spacetype == SPACE_VIEW3D) {
1292                                         View3D *v3d = (View3D *) sl;
1293                                         BGpic *bgpic;
1294
1295                                         for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
1296                                                 if (bgpic->clip == clip)
1297                                                         bgpic->clip = NULL;
1298                                         }
1299                                 }
1300                         }
1301                 }
1302         }
1303
1304         for (sce = bmain->scene.first; sce; sce = sce->id.next) {
1305                 if (sce->clip == clip)
1306                         sce->clip = NULL;
1307         }
1308
1309         for (ob = bmain->object.first; ob; ob = ob->id.next) {
1310                 bConstraint *con;
1311
1312                 for (con = ob->constraints.first; con; con = con->next) {
1313                         bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
1314
1315                         if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
1316                                 bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
1317
1318                                 if (data->clip == clip)
1319                                         data->clip = NULL;
1320                         }
1321                         else if (cti->type == CONSTRAINT_TYPE_CAMERASOLVER) {
1322                                 bCameraSolverConstraint *data = (bCameraSolverConstraint *) con->data;
1323
1324                                 if (data->clip == clip)
1325                                         data->clip = NULL;
1326                         }
1327                         else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
1328                                 bObjectSolverConstraint *data = (bObjectSolverConstraint *) con->data;
1329
1330                                 if (data->clip == clip)
1331                                         data->clip = NULL;
1332                         }
1333                 }
1334         }
1335
1336         {
1337                 bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT);
1338                 treetype->foreach_nodetree(bmain, (void *)clip, &BKE_node_tree_unlink_id_cb);
1339         }
1340
1341         clip->id.us = 0;
1342 }
1343
1344 float BKE_movieclip_remap_scene_to_clip_frame(MovieClip *clip, float framenr)
1345 {
1346         return framenr - (float) clip->start_frame + 1.0f;
1347 }
1348
1349 float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr)
1350 {
1351         return framenr + (float) clip->start_frame - 1.0f;
1352 }