Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / movieclip.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2011 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <fcntl.h>
27
28 #ifndef WIN32
29 #  include <unistd.h>
30 #else
31 #  include <io.h>
32 #endif
33
34 #include <time.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_constraint_types.h"
39 #include "DNA_screen_types.h"
40 #include "DNA_space_types.h"
41 #include "DNA_movieclip_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_view3d_types.h"
46
47 #include "BLI_utildefines.h"
48
49 #include "BLI_blenlib.h"
50 #include "BLI_ghash.h"
51 #include "BLI_math.h"
52 #include "BLI_threads.h"
53
54 #include "BKE_animsys.h"
55 #include "BKE_colortools.h"
56 #include "BKE_library.h"
57 #include "BKE_main.h"
58 #include "BKE_movieclip.h"
59 #include "BKE_node.h"
60 #include "BKE_image.h" /* openanim */
61 #include "BKE_tracking.h"
62
63 #include "IMB_imbuf_types.h"
64 #include "IMB_imbuf.h"
65 #include "IMB_moviecache.h"
66
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_query.h"
69
70 #ifdef WITH_OPENEXR
71 #  include "intern/openexr/openexr_multi.h"
72 #endif
73
74 /*********************** movieclip buffer loaders *************************/
75
76 static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
77 {
78   char num[FILE_MAX] = {0};
79
80   BLI_strncpy(num, full_name + head_len, numlen + 1);
81
82   return atoi(num);
83 }
84
85 static int rendersize_to_proxy(const MovieClipUser *user, int flag)
86 {
87   if ((flag & MCLIP_USE_PROXY) == 0) {
88     return IMB_PROXY_NONE;
89   }
90
91   switch (user->render_size) {
92     case MCLIP_PROXY_RENDER_SIZE_25:
93       return IMB_PROXY_25;
94
95     case MCLIP_PROXY_RENDER_SIZE_50:
96       return IMB_PROXY_50;
97
98     case MCLIP_PROXY_RENDER_SIZE_75:
99       return IMB_PROXY_75;
100
101     case MCLIP_PROXY_RENDER_SIZE_100:
102       return IMB_PROXY_100;
103
104     case MCLIP_PROXY_RENDER_SIZE_FULL:
105       return IMB_PROXY_NONE;
106   }
107
108   return IMB_PROXY_NONE;
109 }
110
111 static int rendersize_to_number(int render_size)
112 {
113   switch (render_size) {
114     case MCLIP_PROXY_RENDER_SIZE_25:
115       return 25;
116
117     case MCLIP_PROXY_RENDER_SIZE_50:
118       return 50;
119
120     case MCLIP_PROXY_RENDER_SIZE_75:
121       return 75;
122
123     case MCLIP_PROXY_RENDER_SIZE_100:
124       return 100;
125
126     case MCLIP_PROXY_RENDER_SIZE_FULL:
127       return 100;
128   }
129
130   return 100;
131 }
132
133 static int get_timecode(MovieClip *clip, int flag)
134 {
135   if ((flag & MCLIP_USE_PROXY) == 0) {
136     return IMB_TC_NONE;
137   }
138
139   return clip->proxy.tc;
140 }
141
142 static void get_sequence_fname(const MovieClip *clip, const int framenr, char *name)
143 {
144   unsigned short numlen;
145   char head[FILE_MAX], tail[FILE_MAX];
146   int offset;
147
148   BLI_strncpy(name, clip->name, sizeof(clip->name));
149   BLI_stringdec(name, head, tail, &numlen);
150
151   /* movieclips always points to first image from sequence,
152    * autoguess offset for now. could be something smarter in the future
153    */
154   offset = sequence_guess_offset(clip->name, strlen(head), numlen);
155
156   if (numlen) {
157     BLI_stringenc(
158         name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
159   }
160   else {
161     BLI_strncpy(name, clip->name, sizeof(clip->name));
162   }
163
164   BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
165 }
166
167 /* supposed to work with sequences only */
168 static void get_proxy_fname(
169     const MovieClip *clip, int proxy_render_size, bool undistorted, int framenr, char *name)
170 {
171   int size = rendersize_to_number(proxy_render_size);
172   char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
173   int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset;
174
175   BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX);
176
177   if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
178     BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
179   }
180   else {
181     BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir);
182   }
183
184   if (undistorted) {
185     BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, proxynr);
186   }
187   else {
188     BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr);
189   }
190
191   BLI_path_abs(name, BKE_main_blendfile_path_from_global());
192   BLI_path_frame(name, 1, 0);
193
194   strcat(name, ".jpg");
195 }
196
197 #ifdef WITH_OPENEXR
198
199 typedef struct MultilayerConvertContext {
200   float *combined_pass;
201   int num_combined_channels;
202 } MultilayerConvertContext;
203
204 static void *movieclip_convert_multilayer_add_view(void *UNUSED(ctx_v),
205                                                    const char *UNUSED(view_name))
206 {
207   return NULL;
208 }
209
210 static void *movieclip_convert_multilayer_add_layer(void *ctx_v, const char *UNUSED(layer_name))
211 {
212   /* Return dummy non-NULL value, we don't use layer handle but need to return
213    * something, so render API invokes the add_pass() callbacks. */
214   return ctx_v;
215 }
216
217 static void movieclip_convert_multilayer_add_pass(void *UNUSED(layer),
218                                                   void *ctx_v,
219                                                   const char *pass_name,
220                                                   float *rect,
221                                                   int num_channels,
222                                                   const char *chan_id,
223                                                   const char *UNUSED(view_name))
224 {
225   /* NOTE: This function must free pass pixels data if it is not used, this
226    * is how IMB_exr_multilayer_convert() is working. */
227   MultilayerConvertContext *ctx = ctx_v;
228   /* If we've found a first combined pass, skip all the rest ones. */
229   if (ctx->combined_pass != NULL) {
230     MEM_freeN(rect);
231     return;
232   }
233   if (STREQ(pass_name, RE_PASSNAME_COMBINED) || STREQ(chan_id, "RGBA") || STREQ(chan_id, "RGB")) {
234     ctx->combined_pass = rect;
235     ctx->num_combined_channels = num_channels;
236   }
237   else {
238     MEM_freeN(rect);
239   }
240 }
241
242 #endif /* WITH_OPENEXR */
243
244 /* Will try to make image buffer usable when originating from the multi-layer
245  * source.
246  * Internally finds a first combined pass and uses that as a buffer. Not ideal,
247  * but is better than a complete empty buffer. */
248 void BKE_movieclip_convert_multilayer_ibuf(struct ImBuf *ibuf)
249 {
250   if (ibuf == NULL) {
251     return;
252   }
253 #ifdef WITH_OPENEXR
254   if (ibuf->ftype != IMB_FTYPE_OPENEXR || ibuf->userdata == NULL) {
255     return;
256   }
257   MultilayerConvertContext ctx;
258   ctx.combined_pass = NULL;
259   ctx.num_combined_channels = 0;
260   IMB_exr_multilayer_convert(ibuf->userdata,
261                              &ctx,
262                              movieclip_convert_multilayer_add_view,
263                              movieclip_convert_multilayer_add_layer,
264                              movieclip_convert_multilayer_add_pass);
265   if (ctx.combined_pass != NULL) {
266     BLI_assert(ibuf->rect_float == NULL);
267     ibuf->rect_float = ctx.combined_pass;
268     ibuf->channels = ctx.num_combined_channels;
269     ibuf->flags |= IB_rectfloat;
270     ibuf->mall |= IB_rectfloat;
271   }
272   IMB_exr_close(ibuf->userdata);
273   ibuf->userdata = NULL;
274 #endif
275 }
276
277 static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
278                                            const MovieClipUser *user,
279                                            int framenr,
280                                            int flag)
281 {
282   struct ImBuf *ibuf;
283   char name[FILE_MAX];
284   int loadflag;
285   bool use_proxy = false;
286   char *colorspace;
287
288   use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
289   if (use_proxy) {
290     int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
291     get_proxy_fname(clip, user->render_size, undistort, framenr, name);
292
293     /* Well, this is a bit weird, but proxies for movie sources
294      * are built in the same exact color space as the input,
295      *
296      * But image sequences are built in the display space.
297      */
298     if (clip->source == MCLIP_SRC_MOVIE) {
299       colorspace = clip->colorspace_settings.name;
300     }
301     else {
302       colorspace = NULL;
303     }
304   }
305   else {
306     get_sequence_fname(clip, framenr, name);
307     colorspace = clip->colorspace_settings.name;
308   }
309
310   loadflag = IB_rect | IB_multilayer | IB_alphamode_detect | IB_metadata;
311
312   /* read ibuf */
313   ibuf = IMB_loadiffname(name, loadflag, colorspace);
314   BKE_movieclip_convert_multilayer_ibuf(ibuf);
315
316   return ibuf;
317 }
318
319 static void movieclip_open_anim_file(MovieClip *clip)
320 {
321   char str[FILE_MAX];
322
323   if (!clip->anim) {
324     BLI_strncpy(str, clip->name, FILE_MAX);
325     BLI_path_abs(str, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
326
327     /* FIXME: make several stream accessible in image editor, too */
328     clip->anim = openanim(str, IB_rect, 0, clip->colorspace_settings.name);
329
330     if (clip->anim) {
331       if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
332         char dir[FILE_MAX];
333         BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
334         BLI_path_abs(dir, BKE_main_blendfile_path_from_global());
335         IMB_anim_set_index_dir(clip->anim, dir);
336       }
337     }
338   }
339 }
340
341 static ImBuf *movieclip_load_movie_file(MovieClip *clip,
342                                         const MovieClipUser *user,
343                                         int framenr,
344                                         int flag)
345 {
346   ImBuf *ibuf = NULL;
347   int tc = get_timecode(clip, flag);
348   int proxy = rendersize_to_proxy(user, flag);
349
350   movieclip_open_anim_file(clip);
351
352   if (clip->anim) {
353     int fra = framenr - clip->start_frame + clip->frame_offset;
354
355     ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
356   }
357
358   return ibuf;
359 }
360
361 static void movieclip_calc_length(MovieClip *clip)
362 {
363   if (clip->source == MCLIP_SRC_MOVIE) {
364     movieclip_open_anim_file(clip);
365
366     if (clip->anim) {
367       clip->len = IMB_anim_get_duration(clip->anim, clip->proxy.tc);
368     }
369   }
370   else if (clip->source == MCLIP_SRC_SEQUENCE) {
371     unsigned short numlen;
372     char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
373
374     BLI_stringdec(clip->name, head, tail, &numlen);
375
376     if (numlen == 0) {
377       /* there's no number group in file name, assume it's single framed sequence */
378       clip->len = 1;
379     }
380     else {
381       clip->len = 0;
382       for (;;) {
383         get_sequence_fname(clip, clip->len + clip->start_frame, name);
384
385         if (BLI_exists(name)) {
386           clip->len++;
387         }
388         else {
389           break;
390         }
391       }
392     }
393   }
394 }
395
396 /*********************** image buffer cache *************************/
397
398 typedef struct MovieClipCache {
399   /* regular movie cache */
400   struct MovieCache *moviecache;
401
402   /* cached postprocessed shot */
403   struct {
404     ImBuf *ibuf;
405     int framenr;
406     int flag;
407
408     /* cache for undistorted shot */
409     float principal[2];
410     float polynomial_k1, polynomial_k2, polynomial_k3;
411     float division_k1, division_k2;
412     short distortion_model;
413     bool undistortion_used;
414
415     int proxy;
416     short render_flag;
417   } postprocessed;
418
419   /* cache for stable shot */
420   struct {
421     ImBuf *reference_ibuf;
422
423     ImBuf *ibuf;
424     int framenr;
425     int postprocess_flag;
426
427     float loc[2], scale, angle, aspect;
428     int proxy, filter;
429     short render_flag;
430   } stabilized;
431
432   int sequence_offset;
433
434   bool is_still_sequence;
435 } MovieClipCache;
436
437 typedef struct MovieClipImBufCacheKey {
438   int framenr;
439   int proxy;
440   short render_flag;
441 } MovieClipImBufCacheKey;
442
443 typedef struct MovieClipCachePriorityData {
444   int framenr;
445 } MovieClipCachePriorityData;
446
447 static int user_frame_to_cache_frame(MovieClip *clip, int framenr)
448 {
449   int index;
450
451   index = framenr - clip->start_frame + clip->frame_offset;
452
453   if (clip->source == MCLIP_SRC_SEQUENCE) {
454     if (clip->cache->sequence_offset == -1) {
455       unsigned short numlen;
456       char head[FILE_MAX], tail[FILE_MAX];
457
458       BLI_stringdec(clip->name, head, tail, &numlen);
459
460       /* see comment in get_sequence_fname */
461       clip->cache->sequence_offset = sequence_guess_offset(clip->name, strlen(head), numlen);
462     }
463
464     index += clip->cache->sequence_offset;
465   }
466
467   if (index < 0) {
468     return framenr - index;
469   }
470
471   return framenr;
472 }
473
474 static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
475 {
476   const MovieClipImBufCacheKey *key = userkey;
477
478   *framenr = key->framenr;
479   *proxy = key->proxy;
480   *render_flags = key->render_flag;
481 }
482
483 static unsigned int moviecache_hashhash(const void *keyv)
484 {
485   const MovieClipImBufCacheKey *key = keyv;
486   int rval = key->framenr;
487
488   return rval;
489 }
490
491 static bool moviecache_hashcmp(const void *av, const void *bv)
492 {
493   const MovieClipImBufCacheKey *a = av;
494   const MovieClipImBufCacheKey *b = bv;
495
496   return ((a->framenr != b->framenr) || (a->proxy != b->proxy) ||
497           (a->render_flag != b->render_flag));
498 }
499
500 static void *moviecache_getprioritydata(void *key_v)
501 {
502   MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)key_v;
503   MovieClipCachePriorityData *priority_data;
504
505   priority_data = MEM_callocN(sizeof(*priority_data), "movie cache clip priority data");
506   priority_data->framenr = key->framenr;
507
508   return priority_data;
509 }
510
511 static int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v)
512 {
513   MovieClipImBufCacheKey *last_userkey = (MovieClipImBufCacheKey *)last_userkey_v;
514   MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *)priority_data_v;
515
516   return -abs(last_userkey->framenr - priority_data->framenr);
517 }
518
519 static void moviecache_prioritydeleter(void *priority_data_v)
520 {
521   MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *)priority_data_v;
522
523   MEM_freeN(priority_data);
524 }
525
526 static ImBuf *get_imbuf_cache(MovieClip *clip, const MovieClipUser *user, int flag)
527 {
528   if (clip->cache) {
529     MovieClipImBufCacheKey key;
530
531     if (!clip->cache->is_still_sequence) {
532       key.framenr = user_frame_to_cache_frame(clip, user->framenr);
533     }
534     else {
535       key.framenr = 1;
536     }
537
538     if (flag & MCLIP_USE_PROXY) {
539       key.proxy = rendersize_to_proxy(user, flag);
540       key.render_flag = user->render_flag;
541     }
542     else {
543       key.proxy = IMB_PROXY_NONE;
544       key.render_flag = 0;
545     }
546
547     return IMB_moviecache_get(clip->cache->moviecache, &key);
548   }
549
550   return NULL;
551 }
552
553 static bool has_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
554 {
555   if (clip->cache) {
556     MovieClipImBufCacheKey key;
557
558     key.framenr = user_frame_to_cache_frame(clip, user->framenr);
559
560     if (flag & MCLIP_USE_PROXY) {
561       key.proxy = rendersize_to_proxy(user, flag);
562       key.render_flag = user->render_flag;
563     }
564     else {
565       key.proxy = IMB_PROXY_NONE;
566       key.render_flag = 0;
567     }
568
569     return IMB_moviecache_has_frame(clip->cache->moviecache, &key);
570   }
571
572   return false;
573 }
574
575 static bool put_imbuf_cache(
576     MovieClip *clip, const MovieClipUser *user, ImBuf *ibuf, int flag, bool destructive)
577 {
578   MovieClipImBufCacheKey key;
579
580   if (clip->cache == NULL) {
581     struct MovieCache *moviecache;
582
583     // char cache_name[64];
584     // BLI_snprintf(cache_name, sizeof(cache_name), "movie %s", clip->id.name);
585
586     clip->cache = MEM_callocN(sizeof(MovieClipCache), "movieClipCache");
587
588     moviecache = IMB_moviecache_create(
589         "movieclip", sizeof(MovieClipImBufCacheKey), moviecache_hashhash, moviecache_hashcmp);
590
591     IMB_moviecache_set_getdata_callback(moviecache, moviecache_keydata);
592     IMB_moviecache_set_priority_callback(moviecache,
593                                          moviecache_getprioritydata,
594                                          moviecache_getitempriority,
595                                          moviecache_prioritydeleter);
596
597     clip->cache->moviecache = moviecache;
598     clip->cache->sequence_offset = -1;
599     if (clip->source == MCLIP_SRC_SEQUENCE) {
600       unsigned short numlen;
601       BLI_stringdec(clip->name, NULL, NULL, &numlen);
602       clip->cache->is_still_sequence = (numlen == 0);
603     }
604   }
605
606   if (!clip->cache->is_still_sequence) {
607     key.framenr = user_frame_to_cache_frame(clip, user->framenr);
608   }
609   else {
610     key.framenr = 1;
611   }
612
613   if (flag & MCLIP_USE_PROXY) {
614     key.proxy = rendersize_to_proxy(user, flag);
615     key.render_flag = user->render_flag;
616   }
617   else {
618     key.proxy = IMB_PROXY_NONE;
619     key.render_flag = 0;
620   }
621
622   if (destructive) {
623     IMB_moviecache_put(clip->cache->moviecache, &key, ibuf);
624     return true;
625   }
626   else {
627     return IMB_moviecache_put_if_possible(clip->cache->moviecache, &key, ibuf);
628   }
629 }
630
631 static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf), void *userkey, void *UNUSED(userdata))
632 {
633   MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey;
634
635   return !(key->proxy == IMB_PROXY_NONE && key->render_flag == 0);
636 }
637
638 /*********************** common functions *************************/
639
640 /* only image block itself */
641 static MovieClip *movieclip_alloc(Main *bmain, const char *name)
642 {
643   MovieClip *clip;
644
645   clip = BKE_libblock_alloc(bmain, ID_MC, name, 0);
646
647   clip->aspx = clip->aspy = 1.0f;
648
649   BKE_tracking_settings_init(&clip->tracking);
650   BKE_color_managed_colorspace_settings_init(&clip->colorspace_settings);
651
652   clip->proxy.build_size_flag = IMB_PROXY_25;
653   clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN | IMB_TC_FREE_RUN |
654                               IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN | IMB_TC_RECORD_RUN_NO_GAPS;
655   clip->proxy.quality = 90;
656
657   clip->start_frame = 1;
658   clip->frame_offset = 0;
659
660   return clip;
661 }
662
663 static void movieclip_load_get_size(MovieClip *clip)
664 {
665   int width, height;
666   MovieClipUser user = {0};
667
668   user.framenr = 1;
669   BKE_movieclip_get_size(clip, &user, &width, &height);
670
671   if (width && height) {
672     clip->tracking.camera.principal[0] = ((float)width) / 2.0f;
673     clip->tracking.camera.principal[1] = ((float)height) / 2.0f;
674   }
675   else {
676     clip->lastsize[0] = clip->lastsize[1] = IMG_SIZE_FALLBACK;
677   }
678 }
679
680 static void detect_clip_source(Main *bmain, MovieClip *clip)
681 {
682   ImBuf *ibuf;
683   char name[FILE_MAX];
684
685   BLI_strncpy(name, clip->name, sizeof(name));
686   BLI_path_abs(name, BKE_main_blendfile_path(bmain));
687
688   ibuf = IMB_testiffname(name, IB_rect | IB_multilayer);
689   if (ibuf) {
690     clip->source = MCLIP_SRC_SEQUENCE;
691     IMB_freeImBuf(ibuf);
692   }
693   else {
694     clip->source = MCLIP_SRC_MOVIE;
695   }
696 }
697
698 /* checks if image was already loaded, then returns same image
699  * otherwise creates new.
700  * does not load ibuf itself
701  * pass on optional frame for #name images */
702 MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
703 {
704   MovieClip *clip;
705   int file;
706   char str[FILE_MAX];
707
708   BLI_strncpy(str, name, sizeof(str));
709   BLI_path_abs(str, BKE_main_blendfile_path(bmain));
710
711   /* exists? */
712   file = BLI_open(str, O_BINARY | O_RDONLY, 0);
713   if (file == -1) {
714     return NULL;
715   }
716   close(file);
717
718   /* ** add new movieclip ** */
719
720   /* create a short library name */
721   clip = movieclip_alloc(bmain, BLI_path_basename(name));
722   BLI_strncpy(clip->name, name, sizeof(clip->name));
723
724   detect_clip_source(bmain, clip);
725
726   movieclip_load_get_size(clip);
727   if (clip->lastsize[0]) {
728     int width = clip->lastsize[0];
729
730     clip->tracking.camera.focal = 24.0f * width / clip->tracking.camera.sensor_width;
731   }
732
733   movieclip_calc_length(clip);
734
735   return clip;
736 }
737
738 MovieClip *BKE_movieclip_file_add_exists_ex(Main *bmain, const char *filepath, bool *r_exists)
739 {
740   MovieClip *clip;
741   char str[FILE_MAX], strtest[FILE_MAX];
742
743   BLI_strncpy(str, filepath, sizeof(str));
744   BLI_path_abs(str, BKE_main_blendfile_path(bmain));
745
746   /* first search an identical filepath */
747   for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
748     BLI_strncpy(strtest, clip->name, sizeof(clip->name));
749     BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &clip->id));
750
751     if (BLI_path_cmp(strtest, str) == 0) {
752       id_us_plus(&clip->id); /* officially should not, it doesn't link here! */
753       if (r_exists) {
754         *r_exists = true;
755       }
756       return clip;
757     }
758   }
759
760   if (r_exists) {
761     *r_exists = false;
762   }
763   return BKE_movieclip_file_add(bmain, filepath);
764 }
765
766 MovieClip *BKE_movieclip_file_add_exists(Main *bmain, const char *filepath)
767 {
768   return BKE_movieclip_file_add_exists_ex(bmain, filepath, NULL);
769 }
770
771 static void real_ibuf_size(
772     const MovieClip *clip, const MovieClipUser *user, const ImBuf *ibuf, int *width, int *height)
773 {
774   *width = ibuf->x;
775   *height = ibuf->y;
776
777   if (clip->flag & MCLIP_USE_PROXY) {
778     switch (user->render_size) {
779       case MCLIP_PROXY_RENDER_SIZE_25:
780         (*width) *= 4;
781         (*height) *= 4;
782         break;
783
784       case MCLIP_PROXY_RENDER_SIZE_50:
785         (*width) *= 2.0f;
786         (*height) *= 2.0f;
787         break;
788
789       case MCLIP_PROXY_RENDER_SIZE_75:
790         *width = ((float)*width) * 4.0f / 3.0f;
791         *height = ((float)*height) * 4.0f / 3.0f;
792         break;
793     }
794   }
795 }
796
797 static ImBuf *get_undistorted_ibuf(MovieClip *clip,
798                                    struct MovieDistortion *distortion,
799                                    ImBuf *ibuf)
800 {
801   ImBuf *undistibuf;
802
803   if (distortion) {
804     undistibuf = BKE_tracking_distortion_exec(
805         distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1);
806   }
807   else {
808     undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f);
809   }
810
811   IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y);
812
813   return undistibuf;
814 }
815
816 static bool need_undistortion_postprocess(const MovieClipUser *user, int clip_flag)
817 {
818   bool result = 0;
819   const bool uses_full_frame = ((clip_flag & MCLIP_USE_PROXY) == 0) ||
820                                (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL);
821   /* Only full undistorted render can be used as on-fly undistorting image. */
822   result |= uses_full_frame && (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
823   return result;
824 }
825
826 static bool need_postprocessed_frame(const MovieClipUser *user,
827                                      int clip_flag,
828                                      int postprocess_flag)
829 {
830   bool result = (postprocess_flag != 0);
831   result |= need_undistortion_postprocess(user, clip_flag);
832   return result;
833 }
834
835 static bool check_undistortion_cache_flags(const MovieClip *clip)
836 {
837   const MovieClipCache *cache = clip->cache;
838   const MovieTrackingCamera *camera = &clip->tracking.camera;
839
840   /* check for distortion model changes */
841   if (!equals_v2v2(camera->principal, cache->postprocessed.principal)) {
842     return false;
843   }
844
845   if (camera->distortion_model != cache->postprocessed.distortion_model) {
846     return false;
847   }
848
849   if (!equals_v3v3(&camera->k1, &cache->postprocessed.polynomial_k1)) {
850     return false;
851   }
852
853   if (!equals_v2v2(&camera->division_k1, &cache->postprocessed.division_k1)) {
854     return false;
855   }
856
857   return true;
858 }
859
860 static ImBuf *get_postprocessed_cached_frame(const MovieClip *clip,
861                                              const MovieClipUser *user,
862                                              int flag,
863                                              int postprocess_flag)
864 {
865   const MovieClipCache *cache = clip->cache;
866   int framenr = user->framenr;
867   short proxy = IMB_PROXY_NONE;
868   int render_flag = 0;
869
870   if (flag & MCLIP_USE_PROXY) {
871     proxy = rendersize_to_proxy(user, flag);
872     render_flag = user->render_flag;
873   }
874
875   /* no cache or no cached postprocessed image */
876   if (!clip->cache || !clip->cache->postprocessed.ibuf) {
877     return NULL;
878   }
879
880   /* postprocessing happened for other frame */
881   if (cache->postprocessed.framenr != framenr) {
882     return NULL;
883   }
884
885   /* cached ibuf used different proxy settings */
886   if (cache->postprocessed.render_flag != render_flag || cache->postprocessed.proxy != proxy) {
887     return NULL;
888   }
889
890   if (cache->postprocessed.flag != postprocess_flag) {
891     return NULL;
892   }
893
894   if (need_undistortion_postprocess(user, flag)) {
895     if (!check_undistortion_cache_flags(clip)) {
896       return NULL;
897     }
898   }
899   else if (cache->postprocessed.undistortion_used) {
900     return NULL;
901   }
902
903   IMB_refImBuf(cache->postprocessed.ibuf);
904
905   return cache->postprocessed.ibuf;
906 }
907
908 static ImBuf *postprocess_frame(
909     MovieClip *clip, const MovieClipUser *user, ImBuf *ibuf, int flag, int postprocess_flag)
910 {
911   ImBuf *postproc_ibuf = NULL;
912
913   if (need_undistortion_postprocess(user, flag)) {
914     postproc_ibuf = get_undistorted_ibuf(clip, NULL, ibuf);
915   }
916   else {
917     postproc_ibuf = IMB_dupImBuf(ibuf);
918   }
919
920   if (postprocess_flag) {
921     bool disable_red = (postprocess_flag & MOVIECLIP_DISABLE_RED) != 0;
922     bool disable_green = (postprocess_flag & MOVIECLIP_DISABLE_GREEN) != 0;
923     bool disable_blue = (postprocess_flag & MOVIECLIP_DISABLE_BLUE) != 0;
924     bool grayscale = (postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE) != 0;
925
926     if (disable_red || disable_green || disable_blue || grayscale) {
927       BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
928     }
929   }
930
931   return postproc_ibuf;
932 }
933
934 static void put_postprocessed_frame_to_cache(
935     MovieClip *clip, const MovieClipUser *user, ImBuf *ibuf, int flag, int postprocess_flag)
936 {
937   MovieClipCache *cache = clip->cache;
938   MovieTrackingCamera *camera = &clip->tracking.camera;
939
940   cache->postprocessed.framenr = user->framenr;
941   cache->postprocessed.flag = postprocess_flag;
942
943   if (flag & MCLIP_USE_PROXY) {
944     cache->postprocessed.proxy = rendersize_to_proxy(user, flag);
945     cache->postprocessed.render_flag = user->render_flag;
946   }
947   else {
948     cache->postprocessed.proxy = IMB_PROXY_NONE;
949     cache->postprocessed.render_flag = 0;
950   }
951
952   if (need_undistortion_postprocess(user, flag)) {
953     cache->postprocessed.distortion_model = camera->distortion_model;
954     copy_v2_v2(cache->postprocessed.principal, camera->principal);
955     copy_v3_v3(&cache->postprocessed.polynomial_k1, &camera->k1);
956     copy_v2_v2(&cache->postprocessed.division_k1, &camera->division_k1);
957     cache->postprocessed.undistortion_used = true;
958   }
959   else {
960     cache->postprocessed.undistortion_used = false;
961   }
962
963   IMB_refImBuf(ibuf);
964
965   if (cache->postprocessed.ibuf) {
966     IMB_freeImBuf(cache->postprocessed.ibuf);
967   }
968
969   cache->postprocessed.ibuf = ibuf;
970 }
971
972 static ImBuf *movieclip_get_postprocessed_ibuf(
973     MovieClip *clip, const MovieClipUser *user, int flag, int postprocess_flag, int cache_flag)
974 {
975   ImBuf *ibuf = NULL;
976   int framenr = user->framenr;
977   bool need_postprocess = false;
978
979   /* cache isn't threadsafe itself and also loading of movies
980    * can't happen from concurrent threads that's why we use lock here */
981   BLI_thread_lock(LOCK_MOVIECLIP);
982
983   /* try to obtain cached postprocessed frame first */
984   if (need_postprocessed_frame(user, flag, postprocess_flag)) {
985     ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag);
986
987     if (!ibuf) {
988       need_postprocess = true;
989     }
990   }
991
992   if (!ibuf) {
993     ibuf = get_imbuf_cache(clip, user, flag);
994   }
995
996   if (!ibuf) {
997     bool use_sequence = false;
998
999     /* undistorted proxies for movies should be read as image sequence */
1000     use_sequence = (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) &&
1001                    (user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL);
1002
1003     if (clip->source == MCLIP_SRC_SEQUENCE || use_sequence) {
1004       ibuf = movieclip_load_sequence_file(clip, user, framenr, flag);
1005     }
1006     else {
1007       ibuf = movieclip_load_movie_file(clip, user, framenr, flag);
1008     }
1009
1010     if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0) {
1011       put_imbuf_cache(clip, user, ibuf, flag, true);
1012     }
1013   }
1014
1015   if (ibuf) {
1016     clip->lastframe = framenr;
1017     real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
1018
1019     /* postprocess frame and put to cache if needed*/
1020     if (need_postprocess) {
1021       ImBuf *tmpibuf = ibuf;
1022       ibuf = postprocess_frame(clip, user, tmpibuf, flag, postprocess_flag);
1023       IMB_freeImBuf(tmpibuf);
1024       if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0) {
1025         put_postprocessed_frame_to_cache(clip, user, ibuf, flag, postprocess_flag);
1026       }
1027     }
1028   }
1029
1030   BLI_thread_unlock(LOCK_MOVIECLIP);
1031
1032   /* Fallback render in case proxies are not enabled or built */
1033   if (!ibuf && user->render_flag & MCLIP_PROXY_RENDER_USE_FALLBACK_RENDER &&
1034       user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL) {
1035     MovieClipUser user_fallback = *user;
1036     user_fallback.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
1037
1038     ibuf = movieclip_get_postprocessed_ibuf(
1039         clip, &user_fallback, flag, postprocess_flag, cache_flag);
1040   }
1041
1042   return ibuf;
1043 }
1044
1045 ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user)
1046 {
1047   return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0);
1048 }
1049
1050 ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag)
1051 {
1052   return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag);
1053 }
1054
1055 ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip,
1056                                             MovieClipUser *user,
1057                                             int postprocess_flag)
1058 {
1059   return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0);
1060 }
1061
1062 static ImBuf *get_stable_cached_frame(
1063     MovieClip *clip, MovieClipUser *user, ImBuf *reference_ibuf, int framenr, int postprocess_flag)
1064 {
1065   MovieClipCache *cache = clip->cache;
1066   MovieTracking *tracking = &clip->tracking;
1067   ImBuf *stableibuf;
1068   float tloc[2], tscale, tangle;
1069   short proxy = IMB_PROXY_NONE;
1070   int render_flag = 0;
1071   int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
1072
1073   if (clip->flag & MCLIP_USE_PROXY) {
1074     proxy = rendersize_to_proxy(user, clip->flag);
1075     render_flag = user->render_flag;
1076   }
1077
1078   /* there's no cached frame or it was calculated for another frame */
1079   if (!cache->stabilized.ibuf || cache->stabilized.framenr != framenr) {
1080     return NULL;
1081   }
1082
1083   if (cache->stabilized.reference_ibuf != reference_ibuf) {
1084     return NULL;
1085   }
1086
1087   /* cached ibuf used different proxy settings */
1088   if (cache->stabilized.render_flag != render_flag || cache->stabilized.proxy != proxy) {
1089     return NULL;
1090   }
1091
1092   if (cache->stabilized.postprocess_flag != postprocess_flag) {
1093     return NULL;
1094   }
1095
1096   /* stabilization also depends on pixel aspect ratio */
1097   if (cache->stabilized.aspect != tracking->camera.pixel_aspect) {
1098     return NULL;
1099   }
1100
1101   if (cache->stabilized.filter != tracking->stabilization.filter) {
1102     return NULL;
1103   }
1104
1105   stableibuf = cache->stabilized.ibuf;
1106
1107   BKE_tracking_stabilization_data_get(
1108       clip, clip_framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle);
1109
1110   /* check for stabilization parameters */
1111   if (tscale != cache->stabilized.scale || tangle != cache->stabilized.angle ||
1112       !equals_v2v2(tloc, cache->stabilized.loc)) {
1113     return NULL;
1114   }
1115
1116   IMB_refImBuf(stableibuf);
1117
1118   return stableibuf;
1119 }
1120
1121 static ImBuf *put_stabilized_frame_to_cache(
1122     MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int framenr, int postprocess_flag)
1123 {
1124   MovieClipCache *cache = clip->cache;
1125   MovieTracking *tracking = &clip->tracking;
1126   ImBuf *stableibuf;
1127   float tloc[2], tscale, tangle;
1128   int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, framenr);
1129
1130   stableibuf = BKE_tracking_stabilize_frame(clip, clip_framenr, ibuf, tloc, &tscale, &tangle);
1131
1132   copy_v2_v2(cache->stabilized.loc, tloc);
1133
1134   cache->stabilized.reference_ibuf = ibuf;
1135   cache->stabilized.scale = tscale;
1136   cache->stabilized.angle = tangle;
1137   cache->stabilized.framenr = framenr;
1138   cache->stabilized.aspect = tracking->camera.pixel_aspect;
1139   cache->stabilized.filter = tracking->stabilization.filter;
1140
1141   if (clip->flag & MCLIP_USE_PROXY) {
1142     cache->stabilized.proxy = rendersize_to_proxy(user, clip->flag);
1143     cache->stabilized.render_flag = user->render_flag;
1144   }
1145   else {
1146     cache->stabilized.proxy = IMB_PROXY_NONE;
1147     cache->stabilized.render_flag = 0;
1148   }
1149
1150   cache->stabilized.postprocess_flag = postprocess_flag;
1151
1152   if (cache->stabilized.ibuf) {
1153     IMB_freeImBuf(cache->stabilized.ibuf);
1154   }
1155
1156   cache->stabilized.ibuf = stableibuf;
1157
1158   IMB_refImBuf(stableibuf);
1159
1160   return stableibuf;
1161 }
1162
1163 ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip,
1164                                      MovieClipUser *user,
1165                                      float loc[2],
1166                                      float *scale,
1167                                      float *angle,
1168                                      int postprocess_flag)
1169 {
1170   ImBuf *ibuf, *stableibuf = NULL;
1171   int framenr = user->framenr;
1172
1173   ibuf = BKE_movieclip_get_postprocessed_ibuf(clip, user, postprocess_flag);
1174
1175   if (!ibuf) {
1176     return NULL;
1177   }
1178
1179   if (clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
1180     MovieClipCache *cache = clip->cache;
1181
1182     stableibuf = get_stable_cached_frame(clip, user, ibuf, framenr, postprocess_flag);
1183
1184     if (!stableibuf) {
1185       stableibuf = put_stabilized_frame_to_cache(clip, user, ibuf, framenr, postprocess_flag);
1186     }
1187
1188     if (loc) {
1189       copy_v2_v2(loc, cache->stabilized.loc);
1190     }
1191
1192     if (scale) {
1193       *scale = cache->stabilized.scale;
1194     }
1195
1196     if (angle) {
1197       *angle = cache->stabilized.angle;
1198     }
1199   }
1200   else {
1201     if (loc) {
1202       zero_v2(loc);
1203     }
1204
1205     if (scale) {
1206       *scale = 1.0f;
1207     }
1208
1209     if (angle) {
1210       *angle = 0.0f;
1211     }
1212
1213     stableibuf = ibuf;
1214   }
1215
1216   if (stableibuf != ibuf) {
1217     IMB_freeImBuf(ibuf);
1218     ibuf = stableibuf;
1219   }
1220
1221   return ibuf;
1222 }
1223
1224 bool BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
1225 {
1226   ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1227
1228   if (ibuf) {
1229     IMB_freeImBuf(ibuf);
1230     return true;
1231   }
1232
1233   return false;
1234 }
1235
1236 void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
1237 {
1238 #if 0
1239   /* originally was needed to support image sequences with different image dimensions,
1240    * which might be useful for such things as reconstruction of unordered image sequence,
1241    * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded
1242    * cache lookups and even unwanted non-proxied files loading when doing mask parenting,
1243    * so let's disable this for now and assume image sequence consists of images with
1244    * equal sizes (sergey)
1245    * TODO(sergey): Support reading sequences of different resolution.
1246    */
1247   if (user->framenr == clip->lastframe) {
1248 #endif
1249   if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
1250     *width = clip->lastsize[0];
1251     *height = clip->lastsize[1];
1252   }
1253   else {
1254     ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1255
1256     if (ibuf && ibuf->x && ibuf->y) {
1257       real_ibuf_size(clip, user, ibuf, width, height);
1258     }
1259     else {
1260       *width = clip->lastsize[0];
1261       *height = clip->lastsize[1];
1262     }
1263
1264     if (ibuf) {
1265       IMB_freeImBuf(ibuf);
1266     }
1267   }
1268 }
1269 void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2])
1270 {
1271   int width, height;
1272   BKE_movieclip_get_size(clip, user, &width, &height);
1273
1274   size[0] = (float)width;
1275   size[1] = (float)height;
1276 }
1277
1278 int BKE_movieclip_get_duration(MovieClip *clip)
1279 {
1280   if (!clip->len) {
1281     movieclip_calc_length(clip);
1282   }
1283
1284   return clip->len;
1285 }
1286
1287 float BKE_movieclip_get_fps(MovieClip *clip)
1288 {
1289   if (clip->source != MCLIP_SRC_MOVIE) {
1290     return 0.0f;
1291   }
1292   movieclip_open_anim_file(clip);
1293   if (clip->anim == NULL) {
1294     return 0.0f;
1295   }
1296   short frs_sec;
1297   float frs_sec_base;
1298   if (IMB_anim_get_fps(clip->anim, &frs_sec, &frs_sec_base, true)) {
1299     return (float)frs_sec / frs_sec_base;
1300   }
1301   return 0.0f;
1302 }
1303
1304 void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy)
1305 {
1306   *aspx = 1.0;
1307
1308   /* x is always 1 */
1309   *aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
1310 }
1311
1312 /* get segments of cached frames. useful for debugging cache policies */
1313 void BKE_movieclip_get_cache_segments(MovieClip *clip,
1314                                       MovieClipUser *user,
1315                                       int *r_totseg,
1316                                       int **r_points)
1317 {
1318   *r_totseg = 0;
1319   *r_points = NULL;
1320
1321   if (clip->cache) {
1322     int proxy = rendersize_to_proxy(user, clip->flag);
1323
1324     IMB_moviecache_get_cache_segments(
1325         clip->cache->moviecache, proxy, user->render_flag, r_totseg, r_points);
1326   }
1327 }
1328
1329 void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
1330 {
1331   /* TODO: clamp framenr here? */
1332
1333   iuser->framenr = framenr;
1334 }
1335
1336 static void free_buffers(MovieClip *clip)
1337 {
1338   if (clip->cache) {
1339     IMB_moviecache_free(clip->cache->moviecache);
1340
1341     if (clip->cache->postprocessed.ibuf) {
1342       IMB_freeImBuf(clip->cache->postprocessed.ibuf);
1343     }
1344
1345     if (clip->cache->stabilized.ibuf) {
1346       IMB_freeImBuf(clip->cache->stabilized.ibuf);
1347     }
1348
1349     MEM_freeN(clip->cache);
1350     clip->cache = NULL;
1351   }
1352
1353   if (clip->anim) {
1354     IMB_free_anim(clip->anim);
1355     clip->anim = NULL;
1356   }
1357 }
1358
1359 void BKE_movieclip_clear_cache(MovieClip *clip)
1360 {
1361   free_buffers(clip);
1362 }
1363
1364 void BKE_movieclip_clear_proxy_cache(MovieClip *clip)
1365 {
1366   if (clip->cache && clip->cache->moviecache) {
1367     IMB_moviecache_cleanup(clip->cache->moviecache, moviecache_check_free_proxy, NULL);
1368   }
1369 }
1370
1371 void BKE_movieclip_reload(Main *bmain, MovieClip *clip)
1372 {
1373   /* clear cache */
1374   free_buffers(clip);
1375
1376   /* update clip source */
1377   detect_clip_source(bmain, clip);
1378
1379   clip->lastsize[0] = clip->lastsize[1] = 0;
1380   movieclip_load_get_size(clip);
1381
1382   movieclip_calc_length(clip);
1383
1384   /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded
1385    * (node trees which are not currently visible wouldn't be refreshed)
1386    */
1387   {
1388     Scene *scene;
1389     for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
1390       if (scene->nodetree) {
1391         nodeUpdateID(scene->nodetree, &clip->id);
1392       }
1393     }
1394   }
1395 }
1396
1397 void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
1398 {
1399   if (scopes->ok) {
1400     return;
1401   }
1402
1403   if (scopes->track_preview) {
1404     IMB_freeImBuf(scopes->track_preview);
1405     scopes->track_preview = NULL;
1406   }
1407
1408   if (scopes->track_search) {
1409     IMB_freeImBuf(scopes->track_search);
1410     scopes->track_search = NULL;
1411   }
1412
1413   scopes->marker = NULL;
1414   scopes->track = NULL;
1415   scopes->track_locked = true;
1416
1417   if (clip) {
1418     MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
1419
1420     if (act_track) {
1421       MovieTrackingTrack *track = act_track;
1422       int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
1423       MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1424
1425       scopes->marker = marker;
1426       scopes->track = track;
1427
1428       if (marker->flag & MARKER_DISABLED) {
1429         scopes->track_disabled = true;
1430       }
1431       else {
1432         ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
1433
1434         scopes->track_disabled = false;
1435
1436         if (ibuf && (ibuf->rect || ibuf->rect_float)) {
1437           MovieTrackingMarker undist_marker = *marker;
1438
1439           if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1440             int width, height;
1441             float aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1442
1443             BKE_movieclip_get_size(clip, user, &width, &height);
1444
1445             undist_marker.pos[0] *= width;
1446             undist_marker.pos[1] *= height * aspy;
1447
1448             BKE_tracking_undistort_v2(&clip->tracking, undist_marker.pos, undist_marker.pos);
1449
1450             undist_marker.pos[0] /= width;
1451             undist_marker.pos[1] /= height * aspy;
1452           }
1453
1454           scopes->track_search = BKE_tracking_get_search_imbuf(
1455               ibuf, track, &undist_marker, true, true);
1456
1457           scopes->undist_marker = undist_marker;
1458
1459           scopes->frame_width = ibuf->x;
1460           scopes->frame_height = ibuf->y;
1461
1462           scopes->use_track_mask = (track->flag & TRACK_PREVIEW_ALPHA) != 0;
1463         }
1464
1465         IMB_freeImBuf(ibuf);
1466       }
1467
1468       if ((track->flag & TRACK_LOCKED) == 0) {
1469         float pat_min[2], pat_max[2];
1470
1471         scopes->track_locked = false;
1472
1473         /* XXX: would work fine with non-transformed patterns, but would likely fail
1474          *      with transformed patterns, but that would be easier to debug when
1475          *      we'll have real pattern sampling (at least to test) */
1476         BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
1477
1478         scopes->slide_scale[0] = pat_max[0] - pat_min[0];
1479         scopes->slide_scale[1] = pat_max[1] - pat_min[1];
1480       }
1481     }
1482   }
1483
1484   scopes->framenr = user->framenr;
1485   scopes->ok = true;
1486 }
1487
1488 static void movieclip_build_proxy_ibuf(
1489     MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, bool undistorted, bool threaded)
1490 {
1491   char name[FILE_MAX];
1492   int quality, rectx, recty;
1493   int size = rendersize_to_number(proxy_render_size);
1494   ImBuf *scaleibuf;
1495
1496   get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);
1497
1498   rectx = ibuf->x * size / 100.0f;
1499   recty = ibuf->y * size / 100.0f;
1500
1501   scaleibuf = IMB_dupImBuf(ibuf);
1502
1503   if (threaded) {
1504     IMB_scaleImBuf_threaded(scaleibuf, (short)rectx, (short)recty);
1505   }
1506   else {
1507     IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
1508   }
1509
1510   quality = clip->proxy.quality;
1511   scaleibuf->ftype = IMB_FTYPE_JPG;
1512   scaleibuf->foptions.quality = quality;
1513   /* unsupported feature only confuses other s/w */
1514   if (scaleibuf->planes == 32) {
1515     scaleibuf->planes = 24;
1516   }
1517
1518   /* TODO: currently the most weak part of multithreaded proxies,
1519    *       could be solved in a way that thread only prepares memory
1520    *       buffer and write to disk happens separately
1521    */
1522   BLI_thread_lock(LOCK_MOVIECLIP);
1523
1524   BLI_make_existing_file(name);
1525   if (IMB_saveiff(scaleibuf, name, IB_rect) == 0) {
1526     perror(name);
1527   }
1528
1529   BLI_thread_unlock(LOCK_MOVIECLIP);
1530
1531   IMB_freeImBuf(scaleibuf);
1532 }
1533
1534 /* note: currently used by proxy job for movies, threading happens within single frame
1535  * (meaning scaling shall be threaded)
1536  */
1537 void BKE_movieclip_build_proxy_frame(MovieClip *clip,
1538                                      int clip_flag,
1539                                      struct MovieDistortion *distortion,
1540                                      int cfra,
1541                                      int *build_sizes,
1542                                      int build_count,
1543                                      bool undistorted)
1544 {
1545   ImBuf *ibuf;
1546   MovieClipUser user;
1547
1548   if (!build_count) {
1549     return;
1550   }
1551
1552   user.framenr = cfra;
1553   user.render_flag = 0;
1554   user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
1555
1556   ibuf = BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP);
1557
1558   if (ibuf) {
1559     ImBuf *tmpibuf = ibuf;
1560     int i;
1561
1562     if (undistorted) {
1563       tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
1564     }
1565
1566     for (i = 0; i < build_count; i++) {
1567       movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, true);
1568     }
1569
1570     IMB_freeImBuf(ibuf);
1571
1572     if (tmpibuf != ibuf) {
1573       IMB_freeImBuf(tmpibuf);
1574     }
1575   }
1576 }
1577
1578 /* note: currently used by proxy job for sequences, threading happens within sequence
1579  * (different threads handles different frames, no threading within frame is needed)
1580  */
1581 void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip,
1582                                               ImBuf *ibuf,
1583                                               struct MovieDistortion *distortion,
1584                                               int cfra,
1585                                               int *build_sizes,
1586                                               int build_count,
1587                                               bool undistorted)
1588 {
1589   if (!build_count) {
1590     return;
1591   }
1592
1593   if (ibuf) {
1594     ImBuf *tmpibuf = ibuf;
1595     int i;
1596
1597     if (undistorted) {
1598       tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
1599     }
1600
1601     for (i = 0; i < build_count; i++) {
1602       movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, false);
1603     }
1604
1605     if (tmpibuf != ibuf) {
1606       IMB_freeImBuf(tmpibuf);
1607     }
1608   }
1609 }
1610
1611 /** Free (or release) any data used by this movie clip (does not free the clip itself). */
1612 void BKE_movieclip_free(MovieClip *clip)
1613 {
1614   /* Also frees animdata. */
1615   free_buffers(clip);
1616
1617   BKE_tracking_free(&clip->tracking);
1618   BKE_animdata_free((ID *)clip, false);
1619 }
1620
1621 /**
1622  * Only copy internal data of MovieClip ID from source to already allocated/initialized destination.
1623  * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
1624  *
1625  * WARNING! This function will not handle ID user count!
1626  *
1627  * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
1628  */
1629 void BKE_movieclip_copy_data(Main *UNUSED(bmain),
1630                              MovieClip *clip_dst,
1631                              const MovieClip *clip_src,
1632                              const int flag)
1633 {
1634   /* We never handle usercount here for own data. */
1635   const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
1636
1637   clip_dst->anim = NULL;
1638   clip_dst->cache = NULL;
1639
1640   BKE_tracking_copy(&clip_dst->tracking, &clip_src->tracking, flag_subdata);
1641   clip_dst->tracking_context = NULL;
1642
1643   BKE_color_managed_colorspace_settings_copy(&clip_dst->colorspace_settings,
1644                                              &clip_src->colorspace_settings);
1645 }
1646
1647 MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
1648 {
1649   MovieClip *clip_copy;
1650   BKE_id_copy(bmain, &clip->id, (ID **)&clip_copy);
1651   return clip_copy;
1652 }
1653
1654 void BKE_movieclip_make_local(Main *bmain, MovieClip *clip, const bool lib_local)
1655 {
1656   BKE_id_make_local_generic(bmain, &clip->id, true, lib_local);
1657 }
1658
1659 float BKE_movieclip_remap_scene_to_clip_frame(const MovieClip *clip, float framenr)
1660 {
1661   return framenr - (float)clip->start_frame + 1.0f;
1662 }
1663
1664 float BKE_movieclip_remap_clip_to_scene_frame(const MovieClip *clip, float framenr)
1665 {
1666   return framenr + (float)clip->start_frame - 1.0f;
1667 }
1668
1669 void BKE_movieclip_filename_for_frame(MovieClip *clip, MovieClipUser *user, char *name)
1670 {
1671   if (clip->source == MCLIP_SRC_SEQUENCE) {
1672     int use_proxy;
1673
1674     use_proxy = (clip->flag & MCLIP_USE_PROXY) &&
1675                 user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
1676
1677     if (use_proxy) {
1678       int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
1679       get_proxy_fname(clip, user->render_size, undistort, user->framenr, name);
1680     }
1681     else {
1682       get_sequence_fname(clip, user->framenr, name);
1683     }
1684   }
1685   else {
1686     BLI_strncpy(name, clip->name, FILE_MAX);
1687     BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
1688   }
1689 }
1690
1691 ImBuf *BKE_movieclip_anim_ibuf_for_frame(MovieClip *clip, MovieClipUser *user)
1692 {
1693   ImBuf *ibuf = NULL;
1694
1695   if (clip->source == MCLIP_SRC_MOVIE) {
1696     BLI_thread_lock(LOCK_MOVIECLIP);
1697     ibuf = movieclip_load_movie_file(clip, user, user->framenr, clip->flag);
1698     BLI_thread_unlock(LOCK_MOVIECLIP);
1699   }
1700
1701   return ibuf;
1702 }
1703
1704 bool BKE_movieclip_has_cached_frame(MovieClip *clip, MovieClipUser *user)
1705 {
1706   bool has_frame = false;
1707
1708   BLI_thread_lock(LOCK_MOVIECLIP);
1709   has_frame = has_imbuf_cache(clip, user, clip->flag);
1710   BLI_thread_unlock(LOCK_MOVIECLIP);
1711
1712   return has_frame;
1713 }
1714
1715 bool BKE_movieclip_put_frame_if_possible(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf)
1716 {
1717   bool result;
1718
1719   BLI_thread_lock(LOCK_MOVIECLIP);
1720   result = put_imbuf_cache(clip, user, ibuf, clip->flag, false);
1721   BLI_thread_unlock(LOCK_MOVIECLIP);
1722
1723   return result;
1724 }
1725
1726 static void movieclip_selection_synchronize(MovieClip *clip_dst, const MovieClip *clip_src)
1727 {
1728   BLI_assert(clip_dst != clip_src);
1729   MovieTracking *tracking_dst = &clip_dst->tracking, tracking_src = clip_src->tracking;
1730   /* Syncs the active object, track and plane track. */
1731   tracking_dst->objectnr = tracking_src.objectnr;
1732   const int active_track_index = BLI_findindex(&tracking_src.tracks, tracking_src.act_track);
1733   const int active_plane_track_index = BLI_findindex(&tracking_src.plane_tracks,
1734                                                      tracking_src.act_plane_track);
1735   tracking_dst->act_track = BLI_findlink(&tracking_dst->tracks, active_track_index);
1736   tracking_dst->act_plane_track = BLI_findlink(&tracking_dst->plane_tracks,
1737                                                active_plane_track_index);
1738
1739   /* Syncs the tracking selection flag. */
1740   MovieTrackingObject *tracking_object_dst, *tracking_object_src;
1741   tracking_object_src = tracking_src.objects.first;
1742
1743   for (tracking_object_dst = tracking_dst->objects.first; tracking_object_dst != NULL;
1744        tracking_object_dst = tracking_object_dst->next,
1745       tracking_object_src = tracking_object_src->next) {
1746     ListBase *tracksbase_dst, *tracksbase_src;
1747     tracksbase_dst = BKE_tracking_object_get_tracks(tracking_dst, tracking_object_dst);
1748     tracksbase_src = BKE_tracking_object_get_tracks(&tracking_src, tracking_object_src);
1749
1750     MovieTrackingTrack *track_dst, *track_src;
1751     track_src = tracksbase_src->first;
1752     for (track_dst = tracksbase_dst->first; track_dst != NULL;
1753          track_dst = track_dst->next, track_src = track_src->next) {
1754       track_dst->flag = track_src->flag;
1755       track_dst->pat_flag = track_src->pat_flag;
1756       track_dst->search_flag = track_src->search_flag;
1757     }
1758   }
1759 }
1760
1761 void BKE_movieclip_eval_update(struct Depsgraph *depsgraph, MovieClip *clip)
1762 {
1763   DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
1764   BKE_tracking_dopesheet_tag_update(&clip->tracking);
1765   if (DEG_is_active(depsgraph)) {
1766     MovieClip *clip_orig = (MovieClip *)DEG_get_original_id(&clip->id);
1767     BKE_tracking_dopesheet_tag_update(&clip_orig->tracking);
1768   }
1769 }
1770
1771 void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip *clip)
1772 {
1773   DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
1774   movieclip_selection_synchronize(clip, (MovieClip *)clip->id.orig_id);
1775 }