~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/movieclip.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

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