Merging r39179 through r39190 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / movieclip.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation,
24  *                 Sergey Sharybin
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/blenkernel/intern/movieclip.c
30  *  \ingroup bke
31  */
32
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <fcntl.h>
37
38 #ifndef WIN32
39 #include <unistd.h>
40 #else
41 #include <io.h>
42 #endif
43
44 #include <time.h>
45
46 #ifdef _WIN32
47 #define open _open
48 #define close _close
49 #endif
50
51 #include "MEM_guardedalloc.h"
52
53 #include "DNA_screen_types.h"
54 #include "DNA_space_types.h"
55 #include "DNA_movieclip_types.h"
56 #include "DNA_object_types.h"   /* SELECT */
57
58 #include "BLI_utildefines.h"
59
60 #include "BLI_blenlib.h"
61 #include "BLI_ghash.h"
62 #include "BLI_math.h"
63 #include "BLI_mempool.h"
64 #include "BLI_threads.h"
65
66 #include "BKE_library.h"
67 #include "BKE_global.h"
68 #include "BKE_main.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_movieclip.h"
71 #include "BKE_moviecache.h"
72 #include "BKE_image.h"  /* openanim */
73 #include "BKE_tracking.h"
74 #include "BKE_animsys.h"
75
76 #include "IMB_imbuf_types.h"
77 #include "IMB_imbuf.h"
78
79 /*********************** movieclip buffer loaders *************************/
80
81 static int sequence_guess_offset(const char *full_name, int head_len, int numlen)
82 {
83         char num[FILE_MAX]= {0};
84
85         strncpy(num, full_name+head_len, numlen);
86
87         return atoi(num);
88 }
89
90 static int rendersize_to_proxy(MovieClip *clip, int flag)
91 {
92         if((flag&MCLIP_USE_PROXY)==0)
93                 return IMB_PROXY_NONE;
94
95         switch(clip->render_size) {
96                 case MCLIP_PROXY_RENDER_SIZE_25:
97                         return IMB_PROXY_25;
98
99                 case MCLIP_PROXY_RENDER_SIZE_50:
100                         return IMB_PROXY_50;
101
102                 case MCLIP_PROXY_RENDER_SIZE_75:
103                         return IMB_PROXY_75;
104
105                 case MCLIP_PROXY_RENDER_SIZE_FULL:
106                         return IMB_PROXY_NONE;
107         }
108
109         return IMB_PROXY_NONE;
110 }
111
112 static int rendersize_to_number(int render_size)
113 {
114         switch(render_size) {
115                 case MCLIP_PROXY_RENDER_SIZE_25:
116                         return 25;
117
118                 case MCLIP_PROXY_RENDER_SIZE_50:
119                         return 50;
120
121                 case MCLIP_PROXY_RENDER_SIZE_75:
122                         return 75;
123
124                 case MCLIP_PROXY_RENDER_SIZE_FULL:
125                         return 100;
126         }
127
128         return 100;
129 }
130
131 static int get_timecode(MovieClip *clip, int flag)
132 {
133         if((flag&MCLIP_USE_PROXY)==0)
134                 return IMB_TC_NONE;
135
136         return clip->proxy.tc;
137 }
138
139 static void get_sequence_fname(MovieClip *clip, int framenr, char *name)
140 {
141         unsigned short numlen;
142         char head[FILE_MAX], tail[FILE_MAX];
143         int offset;
144
145         BLI_strncpy(name, clip->name, sizeof(clip->name));
146         BLI_stringdec(name, head, tail, &numlen);
147
148         /* movieclips always points to first image from sequence,
149            autoguess offset for now. could be something smarter in the future */
150         offset= sequence_guess_offset(clip->name, strlen(head), numlen);
151
152         if(numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1);
153         else strncpy(name, clip->name, sizeof(name));
154
155         if(clip->id.lib)
156                 BLI_path_abs(name, clip->id.lib->filepath);
157         else
158                 BLI_path_abs(name, G.main->name);
159 }
160
161 /* supposed to work with sequences only */
162 static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int framenr, char *name)
163 {
164         int size= rendersize_to_number(proxy_render_size);
165         char dir[FILE_MAX], curname[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
166
167         get_sequence_fname(clip, framenr, curname);
168         BLI_split_dirfile(curname, clipdir, clipfile);
169
170         if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
171                 strcpy(dir, clip->proxy.dir);
172         } else {
173                 BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir);
174         }
175
176         BLI_snprintf(name, FILE_MAX, "%s/images/%d/%s_proxy", dir, size,  clipfile);
177
178         BLI_path_abs(name, G.main->name);
179         BLI_path_frame(name, 1, 0);
180
181         strcat(name, ".jpg");
182 }
183
184 static ImBuf *movieclip_load_sequence_file(MovieClip *clip, int framenr, int flag)
185 {
186         struct ImBuf *ibuf;
187         char name[FILE_MAX];
188         int loadflag, size;
189
190         size= rendersize_to_number(clip->render_size);
191
192         if(flag&MCLIP_USE_PROXY && size!=100) get_proxy_fname(clip, clip->render_size, framenr, name);
193         else get_sequence_fname(clip, framenr, name);
194
195         loadflag= IB_rect|IB_multilayer;
196
197         /* read ibuf */
198         ibuf= IMB_loadiffname(name, loadflag);
199
200         return ibuf;
201 }
202
203 static ImBuf *movieclip_load_movie_file(MovieClip *clip, int framenr, int flag)
204 {
205         ImBuf *ibuf= NULL;
206         int tc= get_timecode(clip, flag);
207         int proxy= rendersize_to_proxy(clip, flag);
208         char str[FILE_MAX];
209
210         if(!clip->anim) {
211                 BLI_strncpy(str, clip->name, FILE_MAX);
212
213                 if(clip->id.lib)
214                         BLI_path_abs(str, clip->id.lib->filepath);
215                 else
216                         BLI_path_abs(str, G.main->name);
217
218                 clip->anim= openanim(str, IB_rect);
219
220
221                 if(clip->anim) {
222                         if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
223                                 char dir[FILE_MAX];
224                                 strcpy(dir, clip->proxy.dir);
225                                 BLI_path_abs(dir, G.main->name);
226                                 IMB_anim_set_index_dir(clip->anim, dir);
227                         }
228                 }
229         }
230
231         if(clip->anim) {
232                 int dur= IMB_anim_get_duration(clip->anim, tc);
233                 int fra= framenr-1;
234
235                 dur= IMB_anim_get_duration(clip->anim, tc);
236                 fra= framenr-1;
237
238                 if(fra<0)
239                         fra= 0;
240
241                 if(fra>(dur-1))
242                         fra= dur-1;
243
244                 ibuf= IMB_anim_absolute(clip->anim, fra, tc, proxy);
245         }
246
247         return ibuf;
248 }
249
250 /*********************** image buffer cache *************************/
251
252 typedef struct MovieClipCache {
253         /* regular moive cache */
254         struct MovieCache *moviecache;
255
256         /* cache for stable shot */
257         int stable_framenr;
258         float stable_loc[2], stable_scale;
259         ImBuf *stableibuf;
260 } MovieClipCache;
261
262 typedef struct MovieClipImBufCacheKey {
263         int framenr;
264         int proxy;
265 } MovieClipImBufCacheKey;
266
267 static void moviecache_keydata(void *userkey, int *framenr, int *proxy)
268 {
269         MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)userkey;
270
271         *framenr= key->framenr;
272         *proxy= key->proxy;
273 }
274
275 static unsigned int moviecache_hashhash(const void *keyv)
276 {
277         MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)keyv;
278         int rval= key->framenr;
279
280         return rval;
281 }
282
283 static int moviecache_hashcmp(const void *av, const void *bv)
284 {
285         const MovieClipImBufCacheKey *a= (MovieClipImBufCacheKey*)av;
286         const MovieClipImBufCacheKey *b= (MovieClipImBufCacheKey*)bv;
287
288         if(a->framenr<b->framenr) return -1;
289         else if(a->framenr>b->framenr) return 1;
290
291         if(a->proxy<b->proxy) return -1;
292         else if(a->proxy>b->proxy) return 1;
293
294         return 0;
295 }
296
297 static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
298 {
299         if(clip->cache) {
300                 MovieClipImBufCacheKey key;
301
302                 key.framenr= user?user->framenr:clip->lastframe;
303
304                 if(flag&MCLIP_USE_PROXY) key.proxy= rendersize_to_proxy(clip, flag);
305                 else key.proxy= IMB_PROXY_NONE;
306
307                 return BKE_moviecache_get(clip->cache->moviecache, &key);
308         }
309
310         return NULL;
311 }
312
313 static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag)
314 {
315         MovieClipImBufCacheKey key;
316
317         if(!clip->cache) {
318                 clip->cache= MEM_callocN(sizeof(MovieClipCache), "movieClipCache");
319
320                 clip->cache->moviecache= BKE_moviecache_create(sizeof(MovieClipImBufCacheKey), moviecache_hashhash,
321                                 moviecache_hashcmp, moviecache_keydata);
322         }
323
324         key.framenr= user?user->framenr:clip->lastframe;
325
326         if(flag&MCLIP_USE_PROXY) key.proxy= rendersize_to_proxy(clip, flag);
327         else key.proxy= IMB_PROXY_NONE;
328
329         BKE_moviecache_put(clip->cache->moviecache, &key, ibuf);
330 }
331
332 /*********************** common functions *************************/
333
334 /* only image block itself */
335 static MovieClip *movieclip_alloc(const char *name)
336 {
337         MovieClip *clip;
338
339         clip= alloc_libblock(&G.main->movieclip, ID_MC, name);
340
341         clip->aspx= clip->aspy= 1.0f;
342
343         clip->tracking.camera.sensor_width= 35.0f;
344         clip->tracking.camera.sensor_height= 18.0f;
345         clip->tracking.camera.units= CAMERA_UNITS_MM;
346
347         clip->tracking.settings.frames_limit= 20;
348         clip->tracking.settings.keyframe1= 1;
349         clip->tracking.settings.keyframe2= 30;
350         clip->tracking.settings.dist= 1;
351
352         clip->tracking.stabilization.scaleinf= 1.f;
353         clip->tracking.stabilization.locinf= 1.f;
354
355         clip->proxy.build_size_flags= IMB_PROXY_25;
356         clip->proxy.build_tc_flags= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN;
357         clip->proxy.quality= 90;
358         clip->render_size= MCLIP_PROXY_RENDER_SIZE_FULL;
359
360         return clip;
361 }
362
363 /* checks if image was already loaded, then returns same image
364    otherwise creates new.
365    does not load ibuf itself
366    pass on optional frame for #name images */
367 MovieClip *BKE_add_movieclip_file(const char *name)
368 {
369         MovieClip *clip;
370         MovieClipUser user;
371         int file, len, width, height;
372         const char *libname;
373         char str[FILE_MAX], strtest[FILE_MAX];
374
375         BLI_strncpy(str, name, sizeof(str));
376         BLI_path_abs(str, G.main->name);
377
378         /* exists? */
379         file= open(str, O_BINARY|O_RDONLY);
380         if(file== -1) return NULL;
381         close(file);
382
383         /* ** first search an identical clip ** */
384         for(clip= G.main->movieclip.first; clip; clip= clip->id.next) {
385                 BLI_strncpy(strtest, clip->name, sizeof(clip->name));
386                 BLI_path_abs(strtest, G.main->name);
387
388                 if(strcmp(strtest, str)==0) {
389                         BLI_strncpy(clip->name, name, sizeof(clip->name));  /* for stringcode */
390                         clip->id.us++;  /* officially should not, it doesn't link here! */
391
392                         return clip;
393                 }
394         }
395
396         /* ** add new movieclip ** */
397
398         /* create a short library name */
399         len= strlen(name);
400
401         while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--;
402         libname= name+len;
403
404         clip= movieclip_alloc(libname);
405         BLI_strncpy(clip->name, name, sizeof(clip->name));
406
407         if(BLI_testextensie_array(name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE;
408         else clip->source= MCLIP_SRC_SEQUENCE;
409
410         user.framenr= 1;
411         BKE_movieclip_acquire_size(clip, &user, &width, &height);
412         if(width && height) {
413                 clip->tracking.camera.principal[0]= ((float)width)/2;
414                 clip->tracking.camera.principal[1]= ((float)height)/2;
415
416                 clip->tracking.camera.focal= 24.f*width/clip->tracking.camera.sensor_width;
417         }
418
419         return clip;
420 }
421
422 static void real_ibuf_size(MovieClip *clip, ImBuf *ibuf, int *width, int *height)
423 {
424         *width= ibuf->x;
425         *height= ibuf->y;
426
427         if(clip->flag&MCLIP_USE_PROXY) {
428                 switch(clip->render_size) {
429                         case MCLIP_PROXY_RENDER_SIZE_25:
430                                 (*width)*= 4;
431                                 (*height)*= 4;
432                                 break;
433
434                         case MCLIP_PROXY_RENDER_SIZE_50:
435                                 (*width)*= 2;
436                                 (*height)*= 2;
437                                 break;
438
439                         case MCLIP_PROXY_RENDER_SIZE_75:
440                                 *width= ((float)*width)*4.f/3.f;
441                                 *height= ((float)*height)*4.f/3.f;
442                                 break;
443                }
444        }
445 }
446
447 ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
448 {
449         ImBuf *ibuf= NULL;
450         int framenr= user?user->framenr:clip->lastframe;
451
452         /* cache isn't threadsafe itself and also loading of movies
453            can't happen from concurent threads that's why we use lock here */
454         BLI_lock_thread(LOCK_MOVIECLIP);
455
456         /* cache is supposed to be threadsafe */
457         ibuf= get_imbuf_cache(clip, user, clip->flag);
458
459         if(!ibuf) {
460                 if(clip->source==MCLIP_SRC_SEQUENCE)
461                         ibuf= movieclip_load_sequence_file(clip, framenr, clip->flag);
462                 else {
463                         ibuf= movieclip_load_movie_file(clip, framenr, clip->flag);
464                 }
465
466                 if(ibuf)
467                         put_imbuf_cache(clip, user, ibuf, clip->flag);
468         }
469
470         if(ibuf) {
471                 clip->lastframe= framenr;
472
473                 real_ibuf_size(clip, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
474         }
475
476         BLI_unlock_thread(LOCK_MOVIECLIP);
477
478         return ibuf;
479 }
480
481 ImBuf *BKE_movieclip_acquire_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag)
482 {
483         ImBuf *ibuf= NULL;
484         int framenr= user?user->framenr:clip->lastframe;
485
486         if(clip->source==MCLIP_SRC_SEQUENCE) {
487                 ibuf= movieclip_load_sequence_file(clip, framenr, flag);
488         } else {
489                 /* loading of movies can't happen from concurent threads */
490                 BLI_lock_thread(LOCK_MOVIECLIP);
491
492                 ibuf= movieclip_load_movie_file(clip, framenr, flag);
493
494                 BLI_unlock_thread(LOCK_MOVIECLIP);
495         }
496
497         return ibuf;
498 }
499
500 ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale)
501 {
502         ImBuf *ibuf, *stableibuf= NULL;
503         int framenr= user?user->framenr:clip->lastframe;
504
505         ibuf= BKE_movieclip_acquire_ibuf(clip, user);
506
507         if(clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
508                 float tloc[2], tscale;
509
510                 if(clip->cache->stableibuf && clip->cache->stable_framenr==framenr) {
511                         stableibuf= clip->cache->stableibuf;
512
513                         BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale);
514
515                         if(!equals_v2v2(tloc, clip->cache->stable_loc) || tscale!=clip->cache->stable_scale) {
516                                 stableibuf= NULL;
517                         }
518                 }
519
520                 if(!stableibuf) {
521                         if(clip->cache->stableibuf)
522                                 IMB_freeImBuf(clip->cache->stableibuf);
523
524                         stableibuf= BKE_tracking_stabilize_shot(&clip->tracking, framenr, ibuf, tloc, &tscale);
525
526                         copy_v2_v2(clip->cache->stable_loc, tloc);
527                         clip->cache->stable_scale= tscale;
528                         clip->cache->stable_framenr= framenr;
529                         clip->cache->stableibuf= stableibuf;
530                 }
531
532                 IMB_refImBuf(stableibuf);
533
534                 if(loc)         copy_v2_v2(loc, tloc);
535                 if(scale)       *scale= tscale;
536         } else {
537                 if(loc)         zero_v2(loc);
538                 if(scale)       *scale= 1.f;
539
540                 stableibuf= ibuf;
541         }
542
543         if(stableibuf!=ibuf) {
544                 IMB_freeImBuf(ibuf);
545                 ibuf= stableibuf;
546         }
547
548         return ibuf;
549
550 }
551
552 int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
553 {
554         ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, user);
555
556         if(ibuf) {
557                 IMB_freeImBuf(ibuf);
558                 return 1;
559         }
560
561         return 0;
562 }
563
564 void BKE_movieclip_acquire_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
565 {
566         if(!user || user->framenr==clip->lastframe) {
567                 *width= clip->lastsize[0];
568                 *height= clip->lastsize[1];
569         } else {
570                 ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, user);
571
572                 if(ibuf && ibuf->x && ibuf->y) {
573                         real_ibuf_size(clip, ibuf, width, height);
574                 } else {
575                         *width= 0;
576                         *height= 0;
577                 }
578
579                 if(ibuf)
580                         IMB_freeImBuf(ibuf);
581         }
582 }
583
584 void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy)
585 {
586         *aspx= *aspy= 1.0;
587
588         /* x is always 1 */
589         *aspy = clip->aspy/clip->aspx;
590 }
591
592 /* get segments of cached frames. useful for debugging cache policies */
593 void BKE_movieclip_get_cache_segments(MovieClip *clip, int *totseg_r, int **points_r)
594 {
595         *totseg_r= 0;
596         *points_r= NULL;
597
598         if(clip->cache) {
599                 int proxy= rendersize_to_proxy(clip, clip->flag);
600
601                 BKE_moviecache_get_cache_segments(clip->cache->moviecache, proxy, totseg_r, points_r);
602         }
603 }
604
605 void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
606 {
607         /* TODO: clamp framenr here? */
608
609         iuser->framenr= framenr;
610 }
611
612 static void free_buffers(MovieClip *clip)
613 {
614         if(clip->cache) {
615                 BKE_moviecache_free(clip->cache->moviecache);
616
617                 if(clip->cache->stableibuf)
618                         IMB_freeImBuf(clip->cache->stableibuf);
619
620                 MEM_freeN(clip->cache);
621                 clip->cache= NULL;
622         }
623
624         if(clip->anim) {
625                 IMB_free_anim(clip->anim);
626                 clip->anim= FALSE;
627         }
628 }
629
630 void BKE_movieclip_reload(MovieClip *clip)
631 {
632         /* clear cache */
633         free_buffers(clip);
634
635         clip->tracking.stabilization.ok= 0;
636
637         /* update clip source */
638         if(BLI_testextensie_array(clip->name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE;
639         else clip->source= MCLIP_SRC_SEQUENCE;
640 }
641
642 /* area - which part of marker should be selected. see TRACK_AREA_* constants */
643 void BKE_movieclip_select_track(MovieClip *clip, MovieTrackingTrack *track, int area, int extend)
644 {
645         if(extend) {
646                 BKE_tracking_track_flag(track, area, SELECT, 0);
647         } else {
648                 MovieTrackingTrack *cur= clip->tracking.tracks.first;
649
650                 while(cur) {
651                         if(cur==track) {
652                                 BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
653                                 BKE_tracking_track_flag(cur, area, SELECT, 0);
654                         }
655                         else {
656                                 BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
657                         }
658
659                         cur= cur->next;
660                 }
661         }
662
663         if(!TRACK_SELECTED(track))
664                 BKE_movieclip_set_selection(clip, MCLIP_SEL_NONE, NULL);
665 }
666
667 void BKE_movieclip_deselect_track(MovieClip *clip, MovieTrackingTrack *track, int area)
668 {
669         BKE_tracking_track_flag(track, area, SELECT, 1);
670
671         if(!TRACK_SELECTED(track))
672                 BKE_movieclip_set_selection(clip, MCLIP_SEL_NONE, NULL);
673 }
674
675 void BKE_movieclip_set_selection(MovieClip *clip, int type, void *sel)
676 {
677         clip->sel_type= type;
678
679         if(type == MCLIP_SEL_NONE) clip->last_sel= NULL;
680         else clip->last_sel= sel;
681 }
682
683 void BKE_movieclip_last_selection(MovieClip *clip, int *type, void **sel)
684 {
685         *type= clip->sel_type;
686
687         if(clip->sel_type == MCLIP_SEL_NONE) *sel= NULL;
688         else *sel= clip->last_sel;
689 }
690
691 void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
692 {
693         void *sel;
694         int sel_type;
695
696         if(scopes->ok) return;
697
698         if(scopes->track_preview) {
699                 IMB_freeImBuf(scopes->track_preview);
700                 scopes->track_preview= NULL;
701         }
702
703         scopes->marker= NULL;
704         scopes->track= NULL;
705
706         if(clip) {
707                 BKE_movieclip_last_selection(clip, &sel_type, &sel);
708
709                 if(sel_type==MCLIP_SEL_TRACK) {
710                         MovieTrackingTrack *track= (MovieTrackingTrack*)sel;
711                         MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
712
713                         if(marker->flag&MARKER_DISABLED) {
714                                 scopes->track_disabled= 1;
715                         } else {
716                                 ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, user);
717
718                                 scopes->track_disabled= 0;
719
720                                 if(ibuf && ibuf->rect) {
721                                         ImBuf *tmpibuf;
722
723                                         tmpibuf= BKE_tracking_acquire_pattern_imbuf(ibuf, track, marker, 1, scopes->track_pos, NULL);
724
725                                         if(tmpibuf->rect_float)
726                                                 IMB_rect_from_float(tmpibuf);
727
728                                         if(tmpibuf->rect)
729                                                 scopes->track_preview= tmpibuf;
730                                         else
731                                                 IMB_freeImBuf(tmpibuf);
732                                 }
733
734                                 IMB_freeImBuf(ibuf);
735                         }
736
737                         if((track->flag&TRACK_LOCKED)==0) {
738                                 scopes->marker= marker;
739                                 scopes->track= track;
740                                 scopes->slide_scale[0]= track->pat_max[0]-track->pat_min[0];
741                                 scopes->slide_scale[1]= track->pat_max[1]-track->pat_min[1];
742                         }
743                 }
744         }
745
746         scopes->framenr= user->framenr;
747         scopes->ok= 1;
748 }
749
750 void BKE_movieclip_build_proxy_frame(MovieClip *clip, int cfra, int proxy_render_size)
751 {
752         char name[FILE_MAXFILE+FILE_MAXDIR];
753         int quality, rectx, recty, size;
754         struct ImBuf * ibuf;
755         MovieClipUser user;
756
757         size= rendersize_to_number(proxy_render_size);
758         user.framenr= cfra;
759
760         get_proxy_fname(clip, proxy_render_size, cfra, name);
761
762         ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &user, 0);
763
764         rectx= ibuf->x*size/100.f;
765         recty= ibuf->y*size/100.f;
766
767         if (ibuf->x != rectx || ibuf->y != recty) {
768                 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
769         }
770
771         quality= clip->proxy.quality;
772         ibuf->ftype= JPG | quality;
773
774         BLI_make_existing_file(name);
775
776         if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)==0)
777                 perror(name);
778
779         IMB_freeImBuf(ibuf);
780 }
781
782 void free_movieclip(MovieClip *clip)
783 {
784         free_buffers(clip);
785
786         BKE_tracking_free(&clip->tracking);
787 }
788
789 void unlink_movieclip(Main *bmain, MovieClip *clip)
790 {
791         bScreen *scr;
792         ScrArea *area;
793         SpaceLink *sl;
794
795         /* text space */
796         for(scr= bmain->screen.first; scr; scr= scr->id.next) {
797                 for(area= scr->areabase.first; area; area= area->next) {
798                         for(sl= area->spacedata.first; sl; sl= sl->next) {
799                                 if(sl->spacetype==SPACE_CLIP) {
800                                         SpaceClip *sc= (SpaceClip*) sl;
801
802                                         if(sc->clip==clip) {
803                                                 sc->clip= NULL;
804                                         }
805                                 }
806                         }
807                 }
808         }
809
810         clip->id.us= 0;
811 }