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