Camera tracking integration
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 8 Aug 2011 12:18:32 +0000 (12:18 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 8 Aug 2011 12:18:32 +0000 (12:18 +0000)
===========================

Initial integration of proxies into movie clip editor.

Known issue: marker preview area uses proxyed image,
             hopefully fix would be available soon.

14 files changed:
release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_moviecache.h
source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/intern/moviecache.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/makesdna/DNA_movieclip_types.h
source/blender/makesrna/intern/rna_movieclip.c

index d6074f5d8dcac0072d8d892b23930ff7387b4304..a3f9658b8f3c76382ac770bd3a616dc322e14509 100644 (file)
@@ -406,6 +406,55 @@ class CLIP_PT_stabilization(bpy.types.Panel):
         row.prop(stab, "influence_scale")
 
 
+class CLIP_PT_proxy(bpy.types.Panel):
+    bl_space_type = 'CLIP_EDITOR'
+    bl_region_type = 'UI'
+    bl_label = "Proxy / Timecode"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        sc = context.space_data
+
+        return sc.clip
+
+    def draw_header(self, context):
+        sc = context.space_data
+
+        self.layout.prop(sc.clip, "use_proxy", text="")
+
+    def draw(self, context):
+        layout = self.layout
+        sc = context.space_data
+        clip = sc.clip
+
+        layout.active = clip.use_proxy
+
+        layout.label(text="Build Sizes:")
+        row = layout.row()
+        row.prop(clip.proxy, "build_25")
+        row.prop(clip.proxy, "build_50")
+        row.prop(clip.proxy, "build_75")
+
+        layout.prop(clip.proxy, "quality")
+
+        layout.prop(clip, 'use_proxy_custom_directory')
+        if clip.use_proxy_custom_directory:
+           layout.prop(clip.proxy, "directory")
+
+        layout.operator("clip.rebuild_proxy", text="Rebuild Proxy")
+
+        if clip.source == 'MOVIE':
+            col = layout.column()
+
+            col.label(text="Use timecode index:")
+            col.prop(clip.proxy, "timecode", text="")
+
+        col = layout.column()
+        col.label(text="Proxy render size:")
+        col.prop(clip, "proxy_render_size", text="")
+
+
 class CLIP_PT_footage(bpy.types.Panel):
     bl_space_type = 'CLIP_EDITOR'
     bl_region_type = 'UI'
index a5e0cc45d09cae4d544c08e558967b75fc185067..37176101062d774c61c19cc52548821d5edb6c03 100644 (file)
@@ -44,7 +44,7 @@
 struct ImBuf;
 struct MovieCache;
 
-typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr);
+typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy);
 
 void BKE_moviecache_init(void);
 void BKE_moviecache_destruct(void);
@@ -53,6 +53,6 @@ struct MovieCache *BKE_moviecache_create(int keysize, GHashHashFP hashfp, GHashC
 void BKE_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
 struct ImBuf* BKE_moviecache_get(struct MovieCache *cache, void *userkey);
 void BKE_moviecache_free(struct MovieCache *cache);
-void BKE_moviecache_get_cache_segments(struct MovieCache *cache, int *totseg_r, int **points_r);
+void BKE_moviecache_get_cache_segments(struct MovieCache *cache, int proxy, int *totseg_r, int **points_r);
 
 #endif
index 259e6ed2dca705f11816ccda7a3bcef4bec56ce2..fbf18c6711f71df513b6fa0d6982a7a6b41eaf8c 100644 (file)
@@ -49,6 +49,7 @@ void BKE_movieclip_reload(struct MovieClip *clip);
 
 struct ImBuf *BKE_movieclip_acquire_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
 struct ImBuf *BKE_movieclip_acquire_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale);
+struct ImBuf *BKE_movieclip_acquire_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag);
 void BKE_movieclip_acquire_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
 void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy);
 int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user);
@@ -63,6 +64,8 @@ void BKE_movieclip_update_scopes(struct MovieClip *clip, struct MovieClipUser *u
 
 void BKE_movieclip_get_cache_segments(struct MovieClip *clip, int *totseg_r, int **points_r);
 
+void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int cfra, int proxy_render_size);
+
 #define TRACK_CLEAR_UPTO               0
 #define TRACK_CLEAR_REMAINED   1
 #define TRACK_CLEAR_ALL                        2
index 6aacf5052e9facfe9922d0d7be727db7f093deb6..e57e55f33c3568130c45ead9a13e558b0f1d02b0 100644 (file)
@@ -58,7 +58,8 @@ typedef struct MovieCache {
        int keysize;
        unsigned long curtime;
 
-       int totseg, *points;    /* for visual statistics optimization */
+       int totseg, *points, points_proxy;      /* for visual statistics optimization */
+       int pad;
 } MovieCache;
 
 typedef struct MovieCacheKey {
@@ -211,6 +212,7 @@ struct MovieCache *BKE_moviecache_create(int keysize, GHashHashFP hashfp, GHashC
        cache->hashfp= hashfp;
        cache->cmpfp= cmpfp;
        cache->getdatafp= getdatafp;
+       cache->points_proxy= -1;
 
        return cache;
 }
@@ -292,7 +294,7 @@ void BKE_moviecache_free(MovieCache *cache)
 }
 
 /* get segments of cached frames. useful for debugging cache policies */
-void BKE_moviecache_get_cache_segments(MovieCache *cache, int *totseg_r, int **points_r)
+void BKE_moviecache_get_cache_segments(MovieCache *cache, int proxy, int *totseg_r, int **points_r)
 {
        *totseg_r= 0;
        *points_r= NULL;
@@ -300,6 +302,13 @@ void BKE_moviecache_get_cache_segments(MovieCache *cache, int *totseg_r, int **p
        if(!cache->getdatafp)
                return;
 
+       if(cache->points_proxy!=proxy) {
+               if(cache->points)
+                       MEM_freeN(cache->points);
+
+               cache->points= NULL;
+       }
+
        if(cache->points) {
                *totseg_r= cache->totseg;
                *points_r= cache->points;
@@ -314,12 +323,13 @@ void BKE_moviecache_get_cache_segments(MovieCache *cache, int *totseg_r, int **p
                while(!BLI_ghashIterator_isDone(iter)) {
                        MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
                        MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
-                       int framenr;
+                       int framenr, curproxy;
 
                        if(item->ibuf) {
-                               cache->getdatafp(key->userkey, &framenr);
+                               cache->getdatafp(key->userkey, &framenr, &curproxy);
 
-                               frames[a++]= framenr;
+                               if(curproxy==proxy)
+                                       frames[a++]= framenr;
                        }
 
                        BLI_ghashIterator_step(iter);
index 0da7baea12777cef4be469644f57540e2c61f732..b77408d61c66d5b665f089943c0fc9fb27243acc 100644 (file)
@@ -87,14 +87,62 @@ static int sequence_guess_offset(const char *full_name, int head_len, int numlen
        return atoi(num);
 }
 
-static ImBuf *movieclip_load_sequence_file(MovieClip *clip, int framenr)
+static int rendersize_to_proxy(MovieClip *clip, int flag)
+{
+       if((flag&MCLIP_USE_PROXY)==0)
+               return IMB_PROXY_NONE;
+
+       switch(clip->render_size) {
+               case MCLIP_PROXY_RENDER_SIZE_25:
+                       return IMB_PROXY_25;
+
+               case MCLIP_PROXY_RENDER_SIZE_50:
+                       return IMB_PROXY_50;
+
+               case MCLIP_PROXY_RENDER_SIZE_75:
+                       return IMB_PROXY_75;
+
+               case MCLIP_PROXY_RENDER_SIZE_FULL:
+                       return IMB_PROXY_NONE;
+       }
+
+       return IMB_PROXY_NONE;
+}
+
+static int rendersize_to_number(int render_size)
+{
+       switch(render_size) {
+               case MCLIP_PROXY_RENDER_SIZE_25:
+                       return 25;
+
+               case MCLIP_PROXY_RENDER_SIZE_50:
+                       return 50;
+
+               case MCLIP_PROXY_RENDER_SIZE_75:
+                       return 75;
+
+               case MCLIP_PROXY_RENDER_SIZE_FULL:
+                       return 100;
+       }
+
+       return 100;
+}
+
+static int get_timecode(MovieClip *clip, int flag)
+{
+       if((flag&MCLIP_USE_PROXY)==0)
+               return IMB_TC_NONE;
+
+       return clip->proxy.tc;
+}
+
+static void get_sequence_fname(MovieClip *clip, int framenr, char *name)
 {
-       struct ImBuf *ibuf;
        unsigned short numlen;
-       char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
-       int flag, offset;
+       char head[FILE_MAX], tail[FILE_MAX];
+       int offset;
 
-       BLI_strncpy(name, clip->name, sizeof(name));
+       BLI_strncpy(name, clip->name, sizeof(clip->name));
        BLI_stringdec(name, head, tail, &numlen);
 
        /* movieclips always points to first image from sequence,
@@ -108,18 +156,55 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, int framenr)
                BLI_path_abs(name, clip->id.lib->filepath);
        else
                BLI_path_abs(name, G.main->name);
+}
+
+/* supposed to work with sequences only */
+static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int framenr, char *name)
+{
+       int size= rendersize_to_number(proxy_render_size);
+       char dir[FILE_MAX], curname[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
+
+       get_sequence_fname(clip, framenr, curname);
+       BLI_split_dirfile(curname, clipdir, clipfile);
+
+       if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
+               strcpy(dir, clip->proxy.dir);
+       } else {
+               snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir);
+       }
+
+       snprintf(name, FILE_MAX, "%s/images/%d/%s_proxy", dir, size,  clipfile);
 
-       flag= IB_rect|IB_multilayer;
+       BLI_path_abs(name, G.main->name);
+       BLI_path_frame(name, 1, 0);
+
+       strcat(name, ".jpg");
+}
+
+static ImBuf *movieclip_load_sequence_file(MovieClip *clip, int framenr, int flag)
+{
+       struct ImBuf *ibuf;
+       char name[FILE_MAX];
+       int loadflag, size;
+
+       size= rendersize_to_number(clip->render_size);
+
+       if(flag&MCLIP_USE_PROXY && size!=100) get_proxy_fname(clip, clip->render_size, framenr, name);
+       else get_sequence_fname(clip, framenr, name);
+
+       loadflag= IB_rect|IB_multilayer;
 
        /* read ibuf */
-       ibuf= IMB_loadiffname(name, flag);
+       ibuf= IMB_loadiffname(name, loadflag);
 
        return ibuf;
 }
 
-static ImBuf *movieclip_load_movie_file(MovieClip *clip, int framenr)
+static ImBuf *movieclip_load_movie_file(MovieClip *clip, int framenr, int flag)
 {
        ImBuf *ibuf= NULL;
+       int tc= get_timecode(clip, flag);
+       int proxy= rendersize_to_proxy(clip, flag);
        char str[FILE_MAX];
 
        if(!clip->anim) {
@@ -131,19 +216,32 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, int framenr)
                        BLI_path_abs(str, G.main->name);
 
                clip->anim= openanim(str, IB_rect);
+
+
+               if(clip->anim) {
+                       if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
+                               char dir[FILE_MAX];
+                               strcpy(dir, clip->proxy.dir);
+                               BLI_path_abs(dir, G.main->name);
+                               IMB_anim_set_index_dir(clip->anim, dir);
+                       }
+               }
        }
 
        if(clip->anim) {
-               int dur= IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+               int dur= IMB_anim_get_duration(clip->anim, tc);
                int fra= framenr-1;
 
+               dur= IMB_anim_get_duration(clip->anim, tc);
+               fra= framenr-1;
+
                if(fra<0)
                        fra= 0;
 
                if(fra>(dur-1))
                        fra= dur-1;
 
-               ibuf= IMB_anim_absolute(clip->anim, fra, IMB_TC_NONE, IMB_PROXY_NONE);
+               ibuf= IMB_anim_absolute(clip->anim, fra, tc, proxy);
        }
 
        return ibuf;
@@ -163,13 +261,15 @@ typedef struct MovieClipCache {
 
 typedef struct MovieClipImBufCacheKey {
        int framenr;
+       int proxy;
 } MovieClipImBufCacheKey;
 
-static void moviecache_keydata(void *userkey, int *framenr)
+static void moviecache_keydata(void *userkey, int *framenr, int *proxy)
 {
        MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)userkey;
 
        *framenr= key->framenr;
+       *proxy= key->proxy;
 }
 
 static unsigned int moviecache_hashhash(const void *keyv)
@@ -188,22 +288,29 @@ static int moviecache_hashcmp(const void *av, const void *bv)
        if(a->framenr<b->framenr) return -1;
        else if(a->framenr>b->framenr) return 1;
 
+       if(a->proxy<b->proxy) return -1;
+       else if(a->proxy>b->proxy) return 1;
+
        return 0;
 }
 
-static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user)
+static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
 {
        if(clip->cache) {
                MovieClipImBufCacheKey key;
 
                key.framenr= user?user->framenr:clip->lastframe;
+
+               if(flag&MCLIP_USE_PROXY) key.proxy= rendersize_to_proxy(clip, flag);
+               else key.proxy= IMB_PROXY_NONE;
+
                return BKE_moviecache_get(clip->cache->moviecache, &key);
        }
 
        return NULL;
 }
 
-static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf)
+static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag)
 {
        MovieClipImBufCacheKey key;
 
@@ -216,6 +323,9 @@ static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf)
 
        key.framenr= user?user->framenr:clip->lastframe;
 
+       if(flag&MCLIP_USE_PROXY) key.proxy= rendersize_to_proxy(clip, flag);
+       else key.proxy= IMB_PROXY_NONE;
+
        BKE_moviecache_put(clip->cache->moviecache, &key, ibuf);
 }
 
@@ -242,6 +352,11 @@ static MovieClip *movieclip_alloc(const char *name)
        clip->tracking.stabilization.scaleinf= 1.f;
        clip->tracking.stabilization.locinf= 1.f;
 
+       clip->proxy.build_size_flags= IMB_PROXY_25;
+       clip->proxy.build_tc_flags= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN;
+       clip->proxy.quality= 90;
+       clip->render_size= MCLIP_PROXY_RENDER_SIZE_FULL;
+
        return clip;
 }
 
@@ -304,6 +419,31 @@ MovieClip *BKE_add_movieclip_file(const char *name)
        return clip;
 }
 
+static void real_ibuf_size(MovieClip *clip, ImBuf *ibuf, int *width, int *height)
+{
+       *width= ibuf->x;
+       *height= ibuf->y;
+
+       if(clip->flag&MCLIP_USE_PROXY) {
+               switch(clip->render_size) {
+                       case MCLIP_PROXY_RENDER_SIZE_25:
+                               (*width)*= 4;
+                               (*height)*= 4;
+                               break;
+
+                       case MCLIP_PROXY_RENDER_SIZE_50:
+                               (*width)*= 2;
+                               (*height)*= 2;
+                               break;
+
+                       case MCLIP_PROXY_RENDER_SIZE_75:
+                               *width= ((float)*width)*4.f/3.f;
+                               *height= ((float)*height)*4.f/3.f;
+                               break;
+               }
+       }
+}
+
 ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
 {
        ImBuf *ibuf= NULL;
@@ -314,24 +454,23 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
        BLI_lock_thread(LOCK_MOVIECLIP);
 
        /* cache is supposed to be threadsafe */
-       ibuf= get_imbuf_cache(clip, user);
+       ibuf= get_imbuf_cache(clip, user, clip->flag);
 
        if(!ibuf) {
                if(clip->source==MCLIP_SRC_SEQUENCE)
-                       ibuf= movieclip_load_sequence_file(clip, framenr);
+                       ibuf= movieclip_load_sequence_file(clip, framenr, clip->flag);
                else {
-                       ibuf= movieclip_load_movie_file(clip, framenr);
+                       ibuf= movieclip_load_movie_file(clip, framenr, clip->flag);
                }
 
                if(ibuf)
-                       put_imbuf_cache(clip, user, ibuf);
+                       put_imbuf_cache(clip, user, ibuf, clip->flag);
        }
 
        if(ibuf) {
                clip->lastframe= framenr;
 
-               clip->lastsize[0]= ibuf->x;
-               clip->lastsize[1]= ibuf->y;
+               real_ibuf_size(clip, ibuf, &clip->lastsize[0], &clip->lastsize[1]);
        }
 
        BLI_unlock_thread(LOCK_MOVIECLIP);
@@ -339,6 +478,25 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
        return ibuf;
 }
 
+ImBuf *BKE_movieclip_acquire_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag)
+{
+       ImBuf *ibuf= NULL;
+       int framenr= user?user->framenr:clip->lastframe;
+
+       if(clip->source==MCLIP_SRC_SEQUENCE) {
+               ibuf= movieclip_load_sequence_file(clip, framenr, flag);
+       } else {
+               /* loading of movies can't happen from concurent threads */
+               BLI_lock_thread(LOCK_MOVIECLIP);
+
+               ibuf= movieclip_load_movie_file(clip, framenr, flag);
+
+               BLI_unlock_thread(LOCK_MOVIECLIP);
+       }
+
+       return ibuf;
+}
+
 ImBuf *BKE_movieclip_acquire_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale)
 {
        ImBuf *ibuf, *stableibuf= NULL;
@@ -412,8 +570,7 @@ void BKE_movieclip_acquire_size(MovieClip *clip, MovieClipUser *user, int *width
                ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, user);
 
                if(ibuf && ibuf->x && ibuf->y) {
-                       *width= ibuf->x;
-                       *height= ibuf->y;
+                       real_ibuf_size(clip, ibuf, width, height);
                } else {
                        *width= 0;
                        *height= 0;
@@ -438,8 +595,11 @@ void BKE_movieclip_get_cache_segments(MovieClip *clip, int *totseg_r, int **poin
        *totseg_r= 0;
        *points_r= NULL;
 
-       if(clip->cache)
-               BKE_moviecache_get_cache_segments(clip->cache->moviecache, totseg_r, points_r);
+       if(clip->cache) {
+               int proxy= rendersize_to_proxy(clip, clip->flag);
+
+               BKE_moviecache_get_cache_segments(clip->cache->moviecache, proxy, totseg_r, points_r);
+       }
 }
 
 void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
@@ -587,6 +747,38 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
        scopes->ok= 1;
 }
 
+void BKE_movieclip_build_proxy_frame(MovieClip *clip, int cfra, int proxy_render_size)
+{
+       char name[FILE_MAXFILE+FILE_MAXDIR];
+       int quality, rectx, recty, size;
+       struct ImBuf * ibuf;
+       MovieClipUser user;
+
+       size= rendersize_to_number(proxy_render_size);
+       user.framenr= cfra;
+
+       get_proxy_fname(clip, proxy_render_size, cfra, name);
+
+       ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &user, 0);
+
+       rectx= ibuf->x*size/100.f;
+       recty= ibuf->y*size/100.f;
+
+       if (ibuf->x != rectx || ibuf->y != recty) {
+               IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
+       }
+
+       quality= clip->proxy.quality;
+       ibuf->ftype= JPG | quality;
+
+       BLI_make_existing_file(name);
+
+       if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)==0)
+               perror(name);
+
+       IMB_freeImBuf(ibuf);
+}
+
 void free_movieclip(MovieClip *clip)
 {
        free_buffers(clip);
index 01fcc6597d89cf443ecf4f4ac3489a47f7037b9a..2a6d6e88c625641a8c42f0667d6166af2f72c8f8 100644 (file)
@@ -804,13 +804,13 @@ int BKE_tracking_next(MovieTrackingContext *context)
        if(!context->num_tracks)
                return 0;
 
-       ibuf= BKE_movieclip_acquire_ibuf(context->clip, &context->user);
+       ibuf= BKE_movieclip_acquire_ibuf_flag(context->clip, &context->user, 0);
        if(!ibuf) return 0;
 
        if(context->backwards) context->user.framenr--;
        else context->user.framenr++;
 
-       ibuf_new= BKE_movieclip_acquire_ibuf(context->clip, &context->user);
+       ibuf_new= BKE_movieclip_acquire_ibuf_flag(context->clip, &context->user, 0);
        if(!ibuf_new) {
                IMB_freeImBuf(ibuf);
                return 0;
index fb90b1e0c9bda79401032ee6f05270099b591788..2000d4462a004e94a2e73923ea8f58dca12a97a7 100644 (file)
@@ -11849,6 +11849,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                clip->aspx= 1.0f;
                                clip->aspy= 1.0f;
                        }
+
+                       /* XXX: a bit hacky, probably include imbuf and use real constants are nicer */
+                       clip->proxy.build_tc_flags= 7;
+                       if(clip->proxy.build_size_flags==0)
+                               clip->proxy.build_size_flags= 1;
+
+                       if(clip->proxy.quality==0)
+                               clip->proxy.quality= 90;
                }
 
                for(cam= main->camera.first; cam; cam= cam->id.next) {
index b6ba399d10a0eeb9df2988951429be511f051c86..de783f437acd94d8345d5e7abeb657b42abea704 100644 (file)
@@ -190,12 +190,13 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        }
 }
 
-static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
+                       int width, int height, float zoomx, float zoomy)
 {
        int x, y;
 
        /* set zoom */
-       glPixelZoom(zoomx, zoomy);
+       glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
 
        /* find window pixel coordinates of origin */
        UI_view2d_to_region_no_clip(&ar->v2d, 0.f, 0.f, &x, &y);
@@ -988,12 +989,14 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
 {
        MovieClip *clip= ED_space_clip(sc);
        ImBuf *ibuf;
+       int width, height;
        float zoomx, zoomy;
 
        /* if no clip, nothing to do */
        if(!clip)
                return;
 
+       ED_space_clip_size(sc, &width, &height);
        ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
 
        if(sc->flag&SC_SHOW_STABLE) {
@@ -1008,10 +1011,10 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
        }
 
        if(ibuf) {
-               draw_movieclip_buffer(sc, ar, ibuf, zoomx, zoomy);
+               draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
                IMB_freeImBuf(ibuf);
 
-               draw_tracking(sc, ar, clip, ibuf->x, ibuf->y, zoomx, zoomy);
+               draw_tracking(sc, ar, clip, width, height, zoomx, zoomy);
        }
 
        draw_movieclip_cache(sc, ar, clip, scene);
index 41dcd637bfafa02d39ad4af67137f8a5b9f4d586..2e786faab3b6a98395a697c7d9caa225cfa64437 100644 (file)
@@ -55,6 +55,7 @@ void CLIP_OT_view_zoom_ratio(struct wmOperatorType *ot);
 void CLIP_OT_view_all(struct wmOperatorType *ot);
 void CLIP_OT_view_selected(struct wmOperatorType *ot);
 void CLIP_OT_change_frame(wmOperatorType *ot);
+void CLIP_OT_rebuild_proxy(struct wmOperatorType *ot);
 
 /* tracking_ops.c */
 void CLIP_OT_select(struct wmOperatorType *ot);
index bd931020794b16f72d1eeb7f4d90d11cc339e233..70dfd6bd6f02aa44a8844c3c651c48d07efd95ad 100644 (file)
@@ -48,6 +48,9 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
 #include "ED_screen.h"
 #include "ED_clip.h"
 
@@ -831,6 +834,105 @@ void CLIP_OT_change_frame(wmOperatorType *ot)
        RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
 }
 
+/********************** rebuild proxies operator *********************/
+
+typedef struct ProxyBuildJob {
+       Scene *scene;
+       struct Main *main;
+       MovieClip *clip;
+} ProxyJob;
+
+static void proxy_freejob(void *pjv)
+{
+       ProxyJob *pj= pjv;
+
+       MEM_freeN(pj);
+}
+
+/* only this runs inside thread */
+static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+{
+       ProxyJob *pj= pjv;
+       Scene *scene=pj->scene;
+       MovieClip *clip= pj->clip;
+       int cfra, tc_flags, size_flags, quality;
+
+       tc_flags= clip->proxy.build_tc_flags;
+       size_flags= clip->proxy.build_size_flags;
+       quality= clip->proxy.quality;
+
+       if (clip->source == MCLIP_SRC_MOVIE) {
+               if (clip->anim)
+                       IMB_anim_index_rebuild(clip->anim, tc_flags, size_flags, quality, stop, do_update, progress);
+
+               return;
+       }
+
+       for(cfra= SFRA; cfra<=EFRA; cfra++) {
+               if (size_flags & IMB_PROXY_25) {
+                       BKE_movieclip_build_proxy_frame(clip, cfra, MCLIP_PROXY_RENDER_SIZE_25);
+               }
+               if (size_flags & IMB_PROXY_50) {
+                       BKE_movieclip_build_proxy_frame(clip, cfra, MCLIP_PROXY_RENDER_SIZE_50);
+               }
+               if (size_flags & IMB_PROXY_75) {
+                       BKE_movieclip_build_proxy_frame(clip, cfra, MCLIP_PROXY_RENDER_SIZE_75);
+               }
+
+               if(*stop || G.afbreek)
+                       break;
+
+               *do_update= 1;
+               *progress= ((float)cfra)/(EFRA-SFRA);
+       }
+}
+
+static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       wmJob * steve;
+       ProxyJob *pj;
+       Scene *scene= CTX_data_scene(C);
+       ScrArea *sa= CTX_wm_area(C);
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+
+       if((clip->flag&MCLIP_USE_PROXY)==0)
+               return OPERATOR_CANCELLED;
+
+       steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS);
+
+       pj= MEM_callocN(sizeof(ProxyJob), "proxy rebuild job");
+       pj->scene= scene;
+       pj->main= CTX_data_main(C);
+       pj->clip= clip;
+
+       WM_jobs_customdata(steve, pj, proxy_freejob);
+       WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0);
+       WM_jobs_callbacks(steve, proxy_startjob, NULL, NULL, NULL);
+
+       G.afbreek= 0;
+       WM_jobs_start(CTX_wm_manager(C), steve);
+
+       ED_area_tag_redraw(CTX_wm_area(C));
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_rebuild_proxy(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Rebuild Proxy and Timecode Indices";
+       ot->idname= "CLIP_OT_rebuild_proxy";
+       ot->description="Rebuild all selected proxies and timecode indeces using the job system";
+
+       /* api callbacks */
+       ot->exec= sequencer_rebuild_proxy_exec;
+       ot->poll= ED_space_clip_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER;
+}
+
 /********************** macroses *********************/
 
 void ED_operatormacros_clip(void)
index 97047bc4a0f895a49b7220696d562db214a74806..c6b418d30dad20cac8c3fb78d0776c7910b90f7c 100644 (file)
@@ -237,10 +237,9 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
 
 static void clip_operatortypes(void)
 {
+       /* ** clip_ops.c ** */
        WM_operatortype_append(CLIP_OT_open);
        WM_operatortype_append(CLIP_OT_reload);
-       WM_operatortype_append(CLIP_OT_tools);
-        WM_operatortype_append(CLIP_OT_properties);
        // WM_operatortype_append(CLIP_OT_unlink);
        WM_operatortype_append(CLIP_OT_view_pan);
        WM_operatortype_append(CLIP_OT_view_zoom);
@@ -250,18 +249,37 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_view_all);
        WM_operatortype_append(CLIP_OT_view_selected);
        WM_operatortype_append(CLIP_OT_change_frame);
+       WM_operatortype_append(CLIP_OT_rebuild_proxy);
+
+       /* ** clip_toolbar.c ** */
+       WM_operatortype_append(CLIP_OT_tools);
+       WM_operatortype_append(CLIP_OT_properties);
+
+       /* ** tracking_ops.c ** */
+
+       /* navigation */
+       WM_operatortype_append(CLIP_OT_frame_jump);
 
+       /* foorage */
+       WM_operatortype_append(CLIP_OT_set_center_principal);
+
+       /* selection */
        WM_operatortype_append(CLIP_OT_select);
        WM_operatortype_append(CLIP_OT_select_all);
        WM_operatortype_append(CLIP_OT_select_border);
        WM_operatortype_append(CLIP_OT_select_circle);
        WM_operatortype_append(CLIP_OT_select_grouped);
 
+       /* markers */
        WM_operatortype_append(CLIP_OT_add_marker);
+       WM_operatortype_append(CLIP_OT_slide_marker);
        WM_operatortype_append(CLIP_OT_delete_track);
        WM_operatortype_append(CLIP_OT_delete_marker);
 
+       /* track */
        WM_operatortype_append(CLIP_OT_track_markers);
+
+       /* solving */
        WM_operatortype_append(CLIP_OT_solve_camera);
        WM_operatortype_append(CLIP_OT_clear_reconstruction);
 
@@ -270,27 +288,25 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_hide_tracks_clear);
        WM_operatortype_append(CLIP_OT_lock_tracks);
 
+       /* orientation */
        WM_operatortype_append(CLIP_OT_set_origin);
        WM_operatortype_append(CLIP_OT_set_floor);
        WM_operatortype_append(CLIP_OT_set_axis);
        WM_operatortype_append(CLIP_OT_set_scale);
 
-       WM_operatortype_append(CLIP_OT_set_center_principal);
-
-       WM_operatortype_append(CLIP_OT_clear_track_path);
-       WM_operatortype_append(CLIP_OT_join_tracks);
-       WM_operatortype_append(CLIP_OT_track_copy_color);
-
-       WM_operatortype_append(CLIP_OT_slide_marker);
-
-       WM_operatortype_append(CLIP_OT_frame_jump);
-
+       /* detect */
        WM_operatortype_append(CLIP_OT_detect_features);
 
+       /* stabilization */
        WM_operatortype_append(CLIP_OT_stabilize_2d_add);
        WM_operatortype_append(CLIP_OT_stabilize_2d_remove);
        WM_operatortype_append(CLIP_OT_stabilize_2d_select);
 
+       /* clean-up */
+       WM_operatortype_append(CLIP_OT_clear_track_path);
+       WM_operatortype_append(CLIP_OT_join_tracks);
+       WM_operatortype_append(CLIP_OT_track_copy_color);
+
        WM_operatortype_append(CLIP_OT_clean_tracks);
 }
 
@@ -308,6 +324,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "CLIP_OT_tools", TKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "CLIP_OT_properties", NKEY, KM_PRESS, 0, 0);
 
+       /* 2d tracking */
        kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
        RNA_boolean_set(kmi->ptr, "backwards", 1);
        WM_keymap_add_item(keymap, "CLIP_OT_track_markers", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
@@ -321,7 +338,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
 
        keymap= WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
 
-       /* View/navigation */
+       /* ** View/navigation ** */
 
        WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
@@ -343,9 +360,25 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
        RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
 
        WM_keymap_add_item(keymap, "CLIP_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
-
        WM_keymap_add_item(keymap, "CLIP_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
 
+       /* jump to special frame */
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "position", 0);
+
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "position", 1);
+
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "position", 2);
+
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "position", 3);
+
+       /* "timeline" */
+       WM_keymap_add_item(keymap, "CLIP_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
+
+       /* selection */
        WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
        WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0);
@@ -354,61 +387,54 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "CLIP_OT_select_circle", CKEY, KM_PRESS, 0, 0);
        WM_keymap_add_menu(keymap, "CLIP_MT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
 
+       /* marker */
        WM_keymap_add_item(keymap, "CLIP_OT_add_marker_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
 
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
-       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
-
-       WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0);
-
        WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0);
 
-       kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0);
-       RNA_string_set(kmi->ptr, "data_path", "space_data.lock_selection");
-
-       WM_keymap_add_menu(keymap, "CLIP_MT_tracking_specials", WKEY, KM_PRESS, 0, 0);
-
        WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0);
 
-       WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0);
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0);
-       RNA_boolean_set(kmi->ptr, "unselected", 1);
-       WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
-
        kmi= WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, 0, 0);
-       RNA_enum_set(kmi->ptr, "action", 2);
+       RNA_enum_set(kmi->ptr, "action", 2);    /* toggle */
+
+       /* tracks */
+       WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0);
 
        kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_CTRL, 0);
-       RNA_enum_set(kmi->ptr, "action", 0);
+       RNA_enum_set(kmi->ptr, "action", 0);    /* lock */
 
        kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_ALT, 0);
-       RNA_enum_set(kmi->ptr, "action", 1);
+       RNA_enum_set(kmi->ptr, "action", 1);    /* unlock */
 
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "position", 0);
+       WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0);
 
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "position", 1);
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0);
+       RNA_boolean_set(kmi->ptr, "unselected", 1);
 
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "position", 2);
+       WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
 
-       kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
-       RNA_enum_set(kmi->ptr, "position", 3);
+       /* clean-up */
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
+       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
+       kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+       RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
 
        WM_keymap_add_item(keymap, "CLIP_OT_join_tracks", JKEY, KM_PRESS, KM_CTRL, 0);
 
+       /* menus */
+       WM_keymap_add_menu(keymap, "CLIP_MT_tracking_specials", WKEY, KM_PRESS, 0, 0);
+
+       /* display */
+       kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0);
+       RNA_string_set(kmi->ptr, "data_path", "space_data.lock_selection");
+
        kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0);
        RNA_string_set(kmi->ptr, "data_path", "space_data.use_mute_footage");
 
-       WM_keymap_add_item(keymap, "CLIP_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
-
        transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
 }
 
index 566fe6108a1008164695c24461ddb795b281dff6..379a5c3504668589f58e9076e2899df0dc2b6db4 100644 (file)
@@ -2189,7 +2189,7 @@ static int detect_features_exec(bContext *C, wmOperator *op)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, &sc->user);
+       ImBuf *ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &sc->user, 0);
        MovieTrackingTrack *track= clip->tracking.tracks.first;
        int margin= RNA_int_get(op->ptr, "margin");
        int min_trackness= RNA_int_get(op->ptr, "min_trackness");
index 9957c233db128d5644956528ccdb4a80a462a86e..5ff08969aac8b18d201963a6043e56c55f19e8bc 100644 (file)
@@ -42,6 +42,7 @@
 
 struct anim;
 struct ImBuf;
+struct MovieClipProxy;
 struct MovieTrackingTrack;
 struct MovieTrackingMarker;
 
@@ -50,6 +51,15 @@ typedef struct MovieClipUser {
        int pad;
 } MovieClipUser;
 
+typedef struct MovieClipProxy {
+       char dir[160];                  /* custom directory for index and proxy files (defaults to BL_proxy) */
+
+       short tc;                               /* time code in use */
+       short quality;                  /* proxy build quality */
+       short build_size_flags; /* size flags (see below) of all proxies to build */
+       short build_tc_flags;   /* time code flags (see below) of all tc indices to build */
+} MovieClipProxy;
+
 typedef struct MovieClip {
        ID id;
 
@@ -69,8 +79,12 @@ typedef struct MovieClip {
                                                                                   used to synchronize data like framenumber
                                                                                   in SpaceClip clip user */
 
+       struct MovieClipProxy proxy;            /* proxy to clip data */
+       short render_size;                                      /* proxy render size */
+       char pad[6];
+       int flag;
+
        int sel_type;           /* last selected thing */
-       int pad;
        void *last_sel;
 } MovieClip;
 
@@ -95,4 +109,14 @@ typedef struct MovieClipScopes {
 #define MCLIP_SEL_NONE         0
 #define MCLIP_SEL_TRACK                1
 
+/* MovieClip->flag */
+#define MCLIP_USE_PROXY                                        (1<<0)
+#define MCLIP_USE_PROXY_CUSTOM_DIR             (1<<1)
+
+/* MovieClip->render_size */
+#define MCLIP_PROXY_RENDER_SIZE_25        0
+#define MCLIP_PROXY_RENDER_SIZE_50        1
+#define MCLIP_PROXY_RENDER_SIZE_75        2
+#define MCLIP_PROXY_RENDER_SIZE_FULL      3
+
 #endif
index 22b26ebec53cd412175a50ad579b439fe0b81aa5..83e4f4f04e8b9d08b6c7321d45b2ef5fdf8143d4 100644 (file)
 
 #include "WM_types.h"
 
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
 #ifdef RNA_RUNTIME
 
 #include "BKE_depsgraph.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
 
 static void rna_MovieClip_reload_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
@@ -87,6 +88,64 @@ static void rna_MovieClip_resolution_get(PointerRNA *ptr, float *values)
 
 #else
 
+static void rna_def_movieclip_proxy(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       static const EnumPropertyItem clip_tc_items[]= {
+               {IMB_TC_NONE, "NONE", 0, "No TC in use", ""},
+               {IMB_TC_RECORD_RUN, "RECORD_RUN", 0, "Record Run", "use images in the order as they are recorded"},
+               {IMB_TC_FREE_RUN, "FREE_RUN", 0, "Free Run", "use global timestamp written by recording device"},
+               {IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN, "FREE_RUN_REC_DATE", 0, "Free Run (rec date)", "interpolate a global timestamp using the record date and time written by recording device"},
+               {0, NULL, 0, NULL, NULL}};
+
+       srna = RNA_def_struct(brna, "MovieClipProxy", NULL);
+       RNA_def_struct_ui_text(srna, "Movie Clip Proxy", "Proxy parameters for a movie clip");
+       RNA_def_struct_sdna(srna, "MovieClipProxy");
+
+       prop= RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", IMB_PROXY_25);
+       RNA_def_property_ui_text(prop, "25%", "Build 25% proxy resolution");
+
+       prop= RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", IMB_PROXY_50);
+       RNA_def_property_ui_text(prop, "50%", "Build 50% proxy resolution");
+
+       prop= RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", IMB_PROXY_75);
+       RNA_def_property_ui_text(prop, "75%", "Build 75% proxy resolution");
+
+       prop= RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flags", IMB_TC_RECORD_RUN);
+       RNA_def_property_ui_text(prop, "Rec Run", "Build record run time code index");
+
+       prop= RNA_def_property(srna, "build_free_run", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flags", IMB_TC_FREE_RUN);
+       RNA_def_property_ui_text(prop, "Free Run", "Build free run time code index");
+
+       prop= RNA_def_property(srna, "build_free_run_rec_date", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flags", IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN);
+       RNA_def_property_ui_text(prop, "Free Run (Rec Date)", "Build free run time code index using Record Date/Time");
+
+       prop= RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_int_sdna(prop, NULL, "quality");
+       RNA_def_property_ui_text(prop, "Quality", "JPEG Quality of proxies to build");
+       RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+
+       prop= RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "tc");
+       RNA_def_property_enum_items(prop, clip_tc_items);
+       RNA_def_property_ui_text(prop, "Timecode", "");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+       /* directory */
+       prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
+       RNA_def_property_string_sdna(prop, NULL, "dir");
+       RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update");
+}
+
 static void rna_def_moviecliUuser(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -116,6 +175,18 @@ static void rna_def_movieclip(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
+       static EnumPropertyItem clip_source_items[]= {
+               {MCLIP_SRC_SEQUENCE, "SEQUENCE", 0, "Image Sequence", "Multiple image files, as a sequence"},
+               {MCLIP_SRC_MOVIE, "MOVIE", 0, "Movie File", "Movie file"},
+               {0, NULL, 0, NULL, NULL}};
+
+       static EnumPropertyItem clip_render_size_items[] = {
+               {MCLIP_PROXY_RENDER_SIZE_25, "PROXY_25", 0, "Proxy size 25%", ""},
+               {MCLIP_PROXY_RENDER_SIZE_50, "PROXY_50", 0, "Proxy size 50%", ""},
+               {MCLIP_PROXY_RENDER_SIZE_75, "PROXY_75", 0, "Proxy size 75%", ""},
+               {MCLIP_PROXY_RENDER_SIZE_FULL, "FULL", 0, "No proxy, full render", ""},
+               {0, NULL, 0, NULL, NULL}};
+
        srna= RNA_def_struct(brna, "MovieClip", "ID");
        RNA_def_struct_ui_text(srna, "MovieClip", "MovieClip datablock referencing an external movie file");
        RNA_def_struct_ui_icon(srna, ICON_SEQUENCE);
@@ -128,6 +199,15 @@ static void rna_def_movieclip(BlenderRNA *brna)
        prop= RNA_def_property(srna, "tracking", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MovieTracking");
 
+       prop= RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "MovieClipProxy");
+
+       /* use proxy */
+       prop= RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY);
+       RNA_def_property_ui_text(prop, "Use Proxy / Timecode", "Use a preview proxy and/or timecode index for this clip");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
        prop= RNA_def_int_vector(srna, "size" , 2 , NULL , 0, 0, "Size" , "Width and height in pixels, zero when image data cant be loaded" , 0 , 0);
        RNA_def_property_int_funcs(prop, "rna_MovieClip_size_get" , NULL, NULL);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -142,11 +222,31 @@ static void rna_def_movieclip(BlenderRNA *brna)
        RNA_def_property_range(prop, 0.1f, 5000.0f);
        RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this clip, does not affect rendering");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+       /* source */
+       prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, clip_source_items);
+       RNA_def_property_ui_text(prop, "Source", "Where the clip comes from");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       /* render size */
+       prop= RNA_def_property(srna, "proxy_render_size", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "render_size");
+       RNA_def_property_enum_items(prop, clip_render_size_items);
+       RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+       /* custom proxy directory */
+       prop= RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY_CUSTOM_DIR);
+       RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Use a custom directory to store data");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update");
 }
 
 void RNA_def_movieclip(BlenderRNA *brna)
 {
        rna_def_movieclip(brna);
+       rna_def_movieclip_proxy(brna);
        rna_def_moviecliUuser(brna);
        rna_def_movieClipScopes(brna);
 }