Merging r51923 through r52851 from trunk into soc-2011-tomato
[blender-staging.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 static void detect_clip_source(MovieClip *clip)
524 {
525         ImBuf *ibuf;
526         char name[FILE_MAX];
527
528         BLI_strncpy(name, clip->name, sizeof(name));
529         BLI_path_abs(name, G.main->name);
530
531         ibuf = IMB_testiffname(name, IB_rect | IB_multilayer);
532         if (ibuf) {
533                 clip->source = MCLIP_SRC_SEQUENCE;
534                 IMB_freeImBuf(ibuf);
535         }
536         else {
537                 clip->source = MCLIP_SRC_MOVIE;
538         }
539 }
540
541 /* checks if image was already loaded, then returns same image
542  * otherwise creates new.
543  * does not load ibuf itself
544  * pass on optional frame for #name images */
545 MovieClip *BKE_movieclip_file_add(const char *name)
546 {
547         MovieClip *clip;
548         int file, len;
549         const char *libname;
550         char str[FILE_MAX], strtest[FILE_MAX];
551
552         BLI_strncpy(str, name, sizeof(str));
553         BLI_path_abs(str, G.main->name);
554
555         /* exists? */
556         file = BLI_open(str, O_BINARY | O_RDONLY, 0);
557         if (file == -1)
558                 return NULL;
559         close(file);
560
561         /* ** first search an identical clip ** */
562         for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
563                 BLI_strncpy(strtest, clip->name, sizeof(clip->name));
564                 BLI_path_abs(strtest, G.main->name);
565
566                 if (strcmp(strtest, str) == 0) {
567                         BLI_strncpy(clip->name, name, sizeof(clip->name));  /* for stringcode */
568                         clip->id.us++;  /* officially should not, it doesn't link here! */
569
570                         return clip;
571                 }
572         }
573
574         /* ** add new movieclip ** */
575
576         /* create a short library name */
577         len = strlen(name);
578
579         while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
580                 len--;
581         libname = name + len;
582
583         clip = movieclip_alloc(libname);
584         BLI_strncpy(clip->name, name, sizeof(clip->name));
585
586         detect_clip_source(clip);
587
588         movieclip_load_get_szie(clip);
589         if (clip->lastsize[0]) {
590                 int width = clip->lastsize[0];
591
592                 clip->tracking.camera.focal = 24.0f * width / clip->tracking.camera.sensor_width;
593         }
594
595         movieclip_calc_length(clip);
596
597         return clip;
598 }
599
600 static void real_ibuf_size(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int *width, int *height)
601 {
602         *width = ibuf->x;
603         *height = ibuf->y;
604
605         if (clip->flag & MCLIP_USE_PROXY) {
606                 switch (user->render_size) {
607                         case MCLIP_PROXY_RENDER_SIZE_25:
608                                 (*width) *= 4;
609                                 (*height) *= 4;
610                                 break;
611
612                         case MCLIP_PROXY_RENDER_SIZE_50:
613                                 (*width) *= 2.0f;
614                                 (*height) *= 2.0f;
615                                 break;
616
617                         case MCLIP_PROXY_RENDER_SIZE_75:
618                                 *width = ((float)*width) * 4.0f / 3.0f;
619                                 *height = ((float)*height) * 4.0f / 3.0f;
620                                 break;
621                 }
622         }
623 }
624
625 static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf)
626 {
627         ImBuf *undistibuf;
628
629         if (distortion)
630                 undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1);
631         else
632                 undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
633
634         IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y);
635
636         return undistibuf;
637 }
638
639 static int need_undistortion_postprocess(MovieClipUser *user)
640 {
641         int result = 0;
642
643         /* only full undistorted render can be used as on-fly undistorting image */
644         result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) &&
645                   (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
646
647         return result;
648 }
649
650 static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag)
651 {
652         int result = postprocess_flag;
653
654         result |= need_undistortion_postprocess(user);
655
656         return result;
657 }
658
659 static int check_undistortion_cache_flags(MovieClip *clip)
660 {
661         MovieClipCache *cache = clip->cache;
662         MovieTrackingCamera *camera = &clip->tracking.camera;
663
664         /* check for distortion model changes */
665         if (!equals_v2v2(camera->principal, cache->postprocessed.principal))
666                 return FALSE;
667
668         if (!equals_v3v3(&camera->k1, &cache->postprocessed.k1))
669                 return FALSE;
670
671         return TRUE;
672 }
673
674 static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag)
675 {
676         MovieClipCache *cache = clip->cache;
677         int framenr = user->framenr;
678         short proxy = IMB_PROXY_NONE;
679         int render_flag = 0;
680
681         if (flag & MCLIP_USE_PROXY) {
682                 proxy = rendersize_to_proxy(user, flag);
683                 render_flag = user->render_flag;
684         }
685
686         /* no cache or no cached postprocessed image */
687         if (!clip->cache || !clip->cache->postprocessed.ibuf)
688                 return NULL;
689
690         /* postprocessing happened for other frame */
691         if (cache->postprocessed.framenr != framenr)
692                 return NULL;
693
694         /* cached ibuf used different proxy settings */
695         if (cache->postprocessed.render_flag != render_flag || cache->postprocessed.proxy != proxy)
696                 return NULL;
697
698         if (cache->postprocessed.flag != postprocess_flag)
699                 return NULL;
700
701         if (need_undistortion_postprocess(user)) {
702                 if (!check_undistortion_cache_flags(clip))
703                         return NULL;
704         }
705         else if (cache->postprocessed.undistortion_used)
706                 return NULL;
707
708         IMB_refImBuf(cache->postprocessed.ibuf);
709
710         return cache->postprocessed.ibuf;
711 }
712
713 static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf,
714                                                int flag, int postprocess_flag)
715 {
716         MovieClipCache *cache = clip->cache;
717         MovieTrackingCamera *camera = &clip->tracking.camera;
718         ImBuf *postproc_ibuf = NULL;
719
720         cache->postprocessed.framenr = user->framenr;
721         cache->postprocessed.flag = postprocess_flag;
722
723         if (flag & MCLIP_USE_PROXY) {
724                 cache->postprocessed.proxy = rendersize_to_proxy(user, flag);
725                 cache->postprocessed.render_flag = user->render_flag;
726         }
727         else {
728                 cache->postprocessed.proxy = IMB_PROXY_NONE;
729                 cache->postprocessed.render_flag = 0;
730         }
731
732         if (need_undistortion_postprocess(user)) {
733                 copy_v2_v2(cache->postprocessed.principal, camera->principal);
734                 copy_v3_v3(&cache->postprocessed.k1, &camera->k1);
735                 cache->postprocessed.undistortion_used = TRUE;
736                 postproc_ibuf = get_undistorted_ibuf(clip, NULL, ibuf);
737         }
738         else {
739                 cache->postprocessed.undistortion_used = FALSE;
740         }
741
742         if (postprocess_flag) {
743                 int disable_red   = postprocess_flag & MOVIECLIP_DISABLE_RED,
744                     disable_green = postprocess_flag & MOVIECLIP_DISABLE_GREEN,
745                     disable_blue  = postprocess_flag & MOVIECLIP_DISABLE_BLUE,
746                     grayscale     = postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE;
747
748                 if (!postproc_ibuf)
749                         postproc_ibuf = IMB_dupImBuf(ibuf);
750
751                 if (disable_red || disable_green || disable_blue || grayscale)
752                         BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
753         }
754
755         IMB_refImBuf(postproc_ibuf);
756
757         if (cache->postprocessed.ibuf)
758                 IMB_freeImBuf(cache->postprocessed.ibuf);
759
760         cache->postprocessed.ibuf = postproc_ibuf;
761
762         return postproc_ibuf;
763 }
764
765 static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int flag,
766                                                int postprocess_flag, int cache_flag)
767 {
768         ImBuf *ibuf = NULL;
769         int framenr = user->framenr, need_postprocess = FALSE;
770
771         /* cache isn't threadsafe itself and also loading of movies
772          * can't happen from concurent threads that's why we use lock here */
773         BLI_lock_thread(LOCK_MOVIECLIP);
774
775         /* try to obtain cached postprocessed frame first */
776         if (need_postprocessed_frame(user, postprocess_flag)) {
777                 ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag);
778
779                 if (!ibuf)
780                         need_postprocess = TRUE;
781         }
782
783         if (!ibuf)
784                 ibuf = get_imbuf_cache(clip, user, flag);
785
786         if (!ibuf) {
787                 int use_sequence = FALSE;
788
789                 /* undistorted proxies for movies should be read as image sequence */
790                 use_sequence = (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) &&
791                                (user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL);
792
793                 if (clip->source == MCLIP_SRC_SEQUENCE || use_sequence) {
794                         ibuf = movieclip_load_sequence_file(clip, user, framenr, flag);
795                 }
796                 else {
797                         ibuf = movieclip_load_movie_file(clip, user, framenr, flag);
798                 }
799
800                 if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0)
801                         put_imbuf_cache(clip, user, ibuf, flag);
802         }
803
804         if (ibuf) {
805                 clip->lastframe = framenr;
806                 real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
807
808                 /* postprocess frame and put to cache */
809                 if (need_postprocess) {
810                         ImBuf *tmpibuf = ibuf;
811                         ibuf = put_postprocessed_frame_to_cache(clip, user, tmpibuf, flag, postprocess_flag);
812                         IMB_freeImBuf(tmpibuf);
813                 }
814         }
815
816         BLI_unlock_thread(LOCK_MOVIECLIP);
817
818         return ibuf;
819 }
820
821 ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user)
822 {
823         return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0);
824 }
825
826 ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag)
827 {
828         return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag);
829 }
830
831 ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int postprocess_flag)
832 {
833         return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0);
834 }
835
836 static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, ImBuf *reference_ibuf,
837                                       int framenr, int postprocess_flag)
838 {
839         MovieClipCache *cache = clip->cache;
840         MovieTracking *tracking = &clip->tracking;
841         ImBuf *stableibuf;
842         float tloc[2], tscale, tangle;
843         short proxy = IMB_PROXY_NONE;
844         int render_flag = 0;
845         int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
846
847         if (clip->flag & MCLIP_USE_PROXY) {
848                 proxy = rendersize_to_proxy(user, clip->flag);
849                 render_flag = user->render_flag;
850         }
851
852         /* there's no cached frame or it was calculated for another frame */
853         if (!cache->stabilized.ibuf || cache->stabilized.framenr != framenr)
854                 return NULL;
855
856         if (cache->stabilized.reference_ibuf != reference_ibuf)
857                 return NULL;
858
859         /* cached ibuf used different proxy settings */
860         if (cache->stabilized.render_flag != render_flag || cache->stabilized.proxy != proxy)
861                 return NULL;
862
863         if (cache->stabilized.postprocess_flag != postprocess_flag)
864                 return NULL;
865
866         /* stabilization also depends on pixel aspect ratio */
867         if (cache->stabilized.aspect != tracking->camera.pixel_aspect)
868                 return NULL;
869
870         if (cache->stabilized.filter != tracking->stabilization.filter)
871                 return NULL;
872
873         stableibuf = cache->stabilized.ibuf;
874
875         BKE_tracking_stabilization_data_get(&clip->tracking, clip_framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
876
877         /* check for stabilization parameters */
878         if (tscale != cache->stabilized.scale ||
879             tangle != cache->stabilized.angle ||
880             !equals_v2v2(tloc, cache->stabilized.loc))
881         {
882                 return NULL;
883         }
884
885         IMB_refImBuf(stableibuf);
886
887         return stableibuf;
888 }
889
890 static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf,
891                                             int framenr, int postprocess_flag)
892 {
893         MovieClipCache *cache = clip->cache;
894         MovieTracking *tracking = &clip->tracking;
895         ImBuf *stableibuf;
896         float tloc[2], tscale, tangle;
897         int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
898
899         stableibuf = BKE_tracking_stabilize_frame(&clip->tracking, clip_framenr, ibuf, tloc, &tscale, &tangle);
900
901         copy_v2_v2(cache->stabilized.loc, tloc);
902
903         cache->stabilized.scale = tscale;
904         cache->stabilized.angle = tangle;
905         cache->stabilized.framenr = framenr;
906         cache->stabilized.aspect = tracking->camera.pixel_aspect;
907         cache->stabilized.filter = tracking->stabilization.filter;
908
909         if (clip->flag & MCLIP_USE_PROXY) {
910                 cache->stabilized.proxy = rendersize_to_proxy(user, clip->flag);
911                 cache->stabilized.render_flag = user->render_flag;
912         }
913         else {
914                 cache->stabilized.proxy = IMB_PROXY_NONE;
915                 cache->stabilized.render_flag = 0;
916         }
917
918         cache->stabilized.postprocess_flag = postprocess_flag;
919
920         if (cache->stabilized.ibuf)
921                 IMB_freeImBuf(cache->stabilized.ibuf);
922
923         cache->stabilized.ibuf = stableibuf;
924
925         IMB_refImBuf(stableibuf);
926
927         return stableibuf;
928 }
929
930 ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle,
931                                      int postprocess_flag)
932 {
933         ImBuf *ibuf, *stableibuf = NULL;
934         int framenr = user->framenr;
935
936         ibuf = BKE_movieclip_get_postprocessed_ibuf(clip, user, postprocess_flag);
937
938         if (!ibuf)
939                 return NULL;
940
941         if (clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
942                 MovieClipCache *cache = clip->cache;
943
944                 stableibuf = get_stable_cached_frame(clip, user, ibuf, framenr, postprocess_flag);
945
946                 if (!stableibuf)
947                         stableibuf = put_stabilized_frame_to_cache(clip, user, ibuf, framenr, postprocess_flag);
948
949                 if (loc)
950                         copy_v2_v2(loc, cache->stabilized.loc);
951
952                 if (scale)
953                         *scale = cache->stabilized.scale;
954
955                 if (angle)
956                         *angle = cache->stabilized.angle;
957         }
958         else {
959                 if (loc)
960                         zero_v2(loc);
961
962                 if (scale)
963                         *scale = 1.0f;
964
965                 if (angle)
966                         *angle = 0.0f;
967
968                 stableibuf = ibuf;
969         }
970
971         if (stableibuf != ibuf) {
972                 IMB_freeImBuf(ibuf);
973                 ibuf = stableibuf;
974         }
975
976         return ibuf;
977
978 }
979
980 int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
981 {
982         ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
983
984         if (ibuf) {
985                 IMB_freeImBuf(ibuf);
986                 return TRUE;
987         }
988
989         return FALSE;
990 }
991
992 void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
993 {
994 #if 0
995         /* originally was needed to support image sequences with different image dimensions,
996          * which might be useful for such things as reconstruction of unordered image sequence,
997          * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded
998          * cache lookups and even unwanted non-proxied files loading when doing mask parenting,
999          * so let's disable this for now and assume image sequence consists of images with
1000          * equal sizes (sergey)
1001          */
1002         if (user->framenr == clip->lastframe) {
1003 #endif
1004         if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
1005                 *width = clip->lastsize[0];
1006                 *height = clip->lastsize[1];
1007         }
1008         else {
1009                 ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1010
1011                 if (ibuf && ibuf->x && ibuf->y) {
1012                         real_ibuf_size(clip, user, ibuf, width, height);
1013                 }
1014                 else {
1015                         *width = clip->lastsize[0];
1016                         *height = clip->lastsize[1];
1017                 }
1018
1019                 if (ibuf)
1020                         IMB_freeImBuf(ibuf);
1021         }
1022 }
1023 void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2])
1024 {
1025         int width, height;
1026         BKE_movieclip_get_size(clip, user, &width, &height);
1027
1028         size[0] = (float)width;
1029         size[1] = (float)height;
1030 }
1031
1032 int BKE_movieclip_get_duration(MovieClip *clip)
1033 {
1034         if (!clip->len) {
1035                 movieclip_calc_length(clip);
1036         }
1037
1038         return clip->len;
1039 }
1040
1041 void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy)
1042 {
1043         *aspx = 1.0;
1044
1045         /* x is always 1 */
1046         *aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
1047 }
1048
1049 /* get segments of cached frames. useful for debugging cache policies */
1050 void BKE_movieclip_get_cache_segments(MovieClip *clip, MovieClipUser *user, int *totseg_r, int **points_r)
1051 {
1052         *totseg_r = 0;
1053         *points_r = NULL;
1054
1055         if (clip->cache) {
1056                 int proxy = rendersize_to_proxy(user, clip->flag);
1057
1058                 IMB_moviecache_get_cache_segments(clip->cache->moviecache, proxy, user->render_flag, totseg_r, points_r);
1059         }
1060 }
1061
1062 void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
1063 {
1064         /* TODO: clamp framenr here? */
1065
1066         iuser->framenr = framenr;
1067 }
1068
1069 static void free_buffers(MovieClip *clip)
1070 {
1071         if (clip->cache) {
1072                 IMB_moviecache_free(clip->cache->moviecache);
1073
1074                 if (clip->cache->postprocessed.ibuf)
1075                         IMB_freeImBuf(clip->cache->postprocessed.ibuf);
1076
1077                 if (clip->cache->stabilized.ibuf)
1078                         IMB_freeImBuf(clip->cache->stabilized.ibuf);
1079
1080                 MEM_freeN(clip->cache);
1081                 clip->cache = NULL;
1082         }
1083
1084         if (clip->anim) {
1085                 IMB_free_anim(clip->anim);
1086                 clip->anim = NULL;
1087         }
1088
1089         BKE_free_animdata((ID *) clip);
1090 }
1091
1092 void BKE_movieclip_reload(MovieClip *clip)
1093 {
1094         /* clear cache */
1095         free_buffers(clip);
1096
1097         clip->tracking.stabilization.ok = FALSE;
1098
1099         /* update clip source */
1100         detect_clip_source(clip);
1101
1102         clip->lastsize[0] = clip->lastsize[1] = 0;
1103         movieclip_load_get_szie(clip);
1104
1105         movieclip_calc_length(clip);
1106
1107         /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded
1108          * (node trees which are not currently visible wouldn't be refreshed)
1109          */
1110         {
1111                 Scene *scene;
1112                 for (scene = G.main->scene.first; scene; scene = scene->id.next) {
1113                         if (scene->nodetree) {
1114                                 nodeUpdateID(scene->nodetree, &clip->id);
1115                         }
1116                 }
1117         }
1118 }
1119
1120 void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
1121 {
1122         if (scopes->ok)
1123                 return;
1124
1125         if (scopes->track_preview) {
1126                 IMB_freeImBuf(scopes->track_preview);
1127                 scopes->track_preview = NULL;
1128         }
1129
1130         if (scopes->track_search) {
1131                 IMB_freeImBuf(scopes->track_search);
1132                 scopes->track_search = NULL;
1133         }
1134
1135         scopes->marker = NULL;
1136         scopes->track = NULL;
1137         scopes->track_locked = TRUE;
1138
1139         if (clip) {
1140                 MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
1141
1142                 if (act_track) {
1143                         MovieTrackingTrack *track = act_track;
1144                         int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
1145                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1146
1147                         scopes->marker = marker;
1148                         scopes->track = track;
1149
1150                         if (marker->flag & MARKER_DISABLED) {
1151                                 scopes->track_disabled = TRUE;
1152                         }
1153                         else {
1154                                 ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1155
1156                                 scopes->track_disabled = FALSE;
1157
1158                                 if (ibuf && (ibuf->rect || ibuf->rect_float)) {
1159                                         ImBuf *search_ibuf;
1160                                         MovieTrackingMarker undist_marker = *marker;
1161
1162                                         if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1163                                                 int width, height;
1164                                                 float aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1165
1166                                                 BKE_movieclip_get_size(clip, user, &width, &height);
1167
1168                                                 undist_marker.pos[0] *= width;
1169                                                 undist_marker.pos[1] *= height * aspy;
1170
1171                                                 BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);
1172
1173                                                 undist_marker.pos[0] /= width;
1174                                                 undist_marker.pos[1] /= height * aspy;
1175                                         }
1176
1177                                         search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE);
1178
1179                                         if (search_ibuf) {
1180                                                 if (!search_ibuf->rect_float) {
1181                                                         /* sampling happens in float buffer */
1182                                                         IMB_float_from_rect(search_ibuf);
1183                                                 }
1184
1185                                                 scopes->track_search = search_ibuf;
1186                                         }
1187
1188                                         scopes->undist_marker = undist_marker;
1189
1190                                         scopes->frame_width = ibuf->x;
1191                                         scopes->frame_height = ibuf->y;
1192
1193                                         scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
1194                                 }
1195
1196                                 IMB_freeImBuf(ibuf);
1197                         }
1198
1199                         if ((track->flag & TRACK_LOCKED) == 0) {
1200                                 float pat_min[2], pat_max[2];
1201
1202                                 scopes->track_locked = FALSE;
1203
1204                                 /* XXX: would work fine with non-transformed patterns, but would likely fail
1205                                  *      with transformed patterns, but that would be easier to debug when
1206                                  *      we'll have real pattern sampling (at least to test) */
1207                                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1208
1209                                 scopes->slide_scale[0] = pat_max[0] - pat_min[0];
1210                                 scopes->slide_scale[1] = pat_max[1] - pat_min[1];
1211                         }
1212                 }
1213         }
1214
1215         scopes->framenr = user->framenr;
1216         scopes->ok = TRUE;
1217 }
1218
1219 static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
1220 {
1221         char name[FILE_MAX];
1222         int quality, rectx, recty;
1223         int size = rendersize_to_number(proxy_render_size);
1224         ImBuf *scaleibuf;
1225
1226         get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);
1227
1228         rectx = ibuf->x * size / 100.0f;
1229         recty = ibuf->y * size / 100.0f;
1230
1231         scaleibuf = IMB_dupImBuf(ibuf);
1232
1233         IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
1234
1235         quality = clip->proxy.quality;
1236         scaleibuf->ftype = JPG | quality;
1237
1238         /* unsupported feature only confuses other s/w */
1239         if (scaleibuf->planes == 32)
1240                 scaleibuf->planes = 24;
1241
1242         BLI_lock_thread(LOCK_MOVIECLIP);
1243
1244         BLI_make_existing_file(name);
1245         if (IMB_saveiff(scaleibuf, name, IB_rect) == 0)
1246                 perror(name);
1247
1248         BLI_unlock_thread(LOCK_MOVIECLIP);
1249
1250         IMB_freeImBuf(scaleibuf);
1251 }
1252
1253 void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
1254                                      int cfra, int *build_sizes, int build_count, int undistorted)
1255 {
1256         ImBuf *ibuf;
1257         MovieClipUser user;
1258
1259         user.framenr = cfra;
1260         user.render_flag = 0;
1261         user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
1262
1263         ibuf = BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP);
1264
1265         if (ibuf) {
1266                 ImBuf *tmpibuf = ibuf;
1267                 int i;
1268
1269                 if (undistorted)
1270                         tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
1271
1272                 for (i = 0; i < build_count; i++)
1273                         movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
1274
1275                 IMB_freeImBuf(ibuf);
1276
1277                 if (tmpibuf != ibuf)
1278                         IMB_freeImBuf(tmpibuf);
1279         }
1280 }
1281
1282 void BKE_movieclip_free(MovieClip *clip)
1283 {
1284         free_buffers(clip);
1285
1286         BKE_tracking_free(&clip->tracking);
1287 }
1288
1289 void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
1290 {
1291         bScreen *scr;
1292         ScrArea *area;
1293         SpaceLink *sl;
1294         Scene *sce;
1295         Object *ob;
1296
1297         for (scr = bmain->screen.first; scr; scr = scr->id.next) {
1298                 for (area = scr->areabase.first; area; area = area->next) {
1299                         for (sl = area->spacedata.first; sl; sl = sl->next) {
1300                                 if (sl->spacetype == SPACE_CLIP) {
1301                                         SpaceClip *sc = (SpaceClip *) sl;
1302
1303                                         if (sc->clip == clip)
1304                                                 sc->clip = NULL;
1305                                 }
1306                                 else if (sl->spacetype == SPACE_VIEW3D) {
1307                                         View3D *v3d = (View3D *) sl;
1308                                         BGpic *bgpic;
1309
1310                                         for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
1311                                                 if (bgpic->clip == clip)
1312                                                         bgpic->clip = NULL;
1313                                         }
1314                                 }
1315                         }
1316                 }
1317         }
1318
1319         for (sce = bmain->scene.first; sce; sce = sce->id.next) {
1320                 if (sce->clip == clip)
1321                         sce->clip = NULL;
1322         }
1323
1324         for (ob = bmain->object.first; ob; ob = ob->id.next) {
1325                 bConstraint *con;
1326
1327                 for (con = ob->constraints.first; con; con = con->next) {
1328                         bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
1329
1330                         if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
1331                                 bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
1332
1333                                 if (data->clip == clip)
1334                                         data->clip = NULL;
1335                         }
1336                         else if (cti->type == CONSTRAINT_TYPE_CAMERASOLVER) {
1337                                 bCameraSolverConstraint *data = (bCameraSolverConstraint *) con->data;
1338
1339                                 if (data->clip == clip)
1340                                         data->clip = NULL;
1341                         }
1342                         else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
1343                                 bObjectSolverConstraint *data = (bObjectSolverConstraint *) con->data;
1344
1345                                 if (data->clip == clip)
1346                                         data->clip = NULL;
1347                         }
1348                 }
1349         }
1350
1351         {
1352                 bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT);
1353                 treetype->foreach_nodetree(bmain, (void *)clip, &BKE_node_tree_unlink_id_cb);
1354         }
1355
1356         clip->id.us = 0;
1357 }
1358
1359 float BKE_movieclip_remap_scene_to_clip_frame(MovieClip *clip, float framenr)
1360 {
1361         return framenr - (float) clip->start_frame + 1.0f;
1362 }
1363
1364 float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr)
1365 {
1366         return framenr + (float) clip->start_frame - 1.0f;
1367 }