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