Merged changes in the trunk up to revision 55357.
[blender-staging.git] / source / blender / blenkernel / intern / movieclip.c
index 4156b5b43679c0699106d410f897de06b44e643f..e79754ca203b9e26f97cc5cf30d2a632e618ebd1 100644 (file)
 #include "BKE_node.h"
 #include "BKE_image.h"  /* openanim */
 #include "BKE_tracking.h"
+#include "BKE_sequencer.h"
 
 #include "IMB_colormanagement.h"
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 #include "IMB_moviecache.h"
 
+#ifdef WITH_OPENEXR
+#include "intern/openexr/openexr_multi.h"
+#endif
+
 /*********************** movieclip buffer loaders *************************/
 
 static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
@@ -216,11 +221,20 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
                colorspace = clip->colorspace_settings.name;
        }
 
-       loadflag = IB_rect | IB_multilayer;
+       loadflag = IB_rect | IB_multilayer | IB_alphamode_detect;
 
        /* read ibuf */
        ibuf = IMB_loadiffname(name, loadflag, colorspace);
 
+#ifdef WITH_OPENEXR
+       if (ibuf) {
+               if (ibuf->ftype == OPENEXR && ibuf->userdata) {
+                       IMB_exr_close(ibuf->userdata);
+                       ibuf->userdata = NULL;
+               }
+       }
+#endif
+
        return ibuf;
 }
 
@@ -479,11 +493,11 @@ static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
 /*********************** common functions *************************/
 
 /* only image block itself */
-static MovieClip *movieclip_alloc(const char *name)
+static MovieClip *movieclip_alloc(Main *bmain, const char *name)
 {
        MovieClip *clip;
 
-       clip = BKE_libblock_alloc(&G.main->movieclip, ID_MC, name);
+       clip = BKE_libblock_alloc(&bmain->movieclip, ID_MC, name);
 
        clip->aspx = clip->aspy = 1.0f;
 
@@ -542,7 +556,7 @@ static void detect_clip_source(MovieClip *clip)
  * otherwise creates new.
  * does not load ibuf itself
  * pass on optional frame for #name images */
-MovieClip *BKE_movieclip_file_add(const char *name)
+MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
 {
        MovieClip *clip;
        int file, len;
@@ -550,7 +564,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
        char str[FILE_MAX], strtest[FILE_MAX];
 
        BLI_strncpy(str, name, sizeof(str));
-       BLI_path_abs(str, G.main->name);
+       BLI_path_abs(str, bmain->name);
 
        /* exists? */
        file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -559,7 +573,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
        close(file);
 
        /* ** first search an identical clip ** */
-       for (clip = G.main->movieclip.first; clip; clip = clip->id.next) {
+       for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
                BLI_strncpy(strtest, clip->name, sizeof(clip->name));
                BLI_path_abs(strtest, G.main->name);
 
@@ -580,7 +594,7 @@ MovieClip *BKE_movieclip_file_add(const char *name)
                len--;
        libname = name + len;
 
-       clip = movieclip_alloc(libname);
+       clip = movieclip_alloc(bmain, libname);
        BLI_strncpy(clip->name, name, sizeof(clip->name));
 
        detect_clip_source(clip);
@@ -1216,7 +1230,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
        scopes->ok = TRUE;
 }
 
-static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
+static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted, bool threaded)
 {
        char name[FILE_MAX];
        int quality, rectx, recty;
@@ -1230,7 +1244,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
 
        scaleibuf = IMB_dupImBuf(ibuf);
 
-       IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
+       if (threaded)
+               IMB_scaleImBuf_threaded(scaleibuf, (short)rectx, (short)recty);
+       else
+               IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
 
        quality = clip->proxy.quality;
        scaleibuf->ftype = JPG | quality;
@@ -1239,6 +1256,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
        if (scaleibuf->planes == 32)
                scaleibuf->planes = 24;
 
+       /* TODO: currently the most weak part of multithreaded proxies,
+        *       could be solved in a way that thread only prepares memory
+        *       buffer and write to disk happens separately
+        */
        BLI_lock_thread(LOCK_MOVIECLIP);
 
        BLI_make_existing_file(name);
@@ -1250,12 +1271,18 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
        IMB_freeImBuf(scaleibuf);
 }
 
+/* note: currently used by proxy job for movies, threading happens within single frame
+ * (meaning scaling shall be threaded)
+ */
 void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
                                      int cfra, int *build_sizes, int build_count, int undistorted)
 {
        ImBuf *ibuf;
        MovieClipUser user;
 
+       if (!build_count)
+               return;
+
        user.framenr = cfra;
        user.render_flag = 0;
        user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
@@ -1270,7 +1297,7 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
                        tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
 
                for (i = 0; i < build_count; i++)
-                       movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
+                       movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, true);
 
                IMB_freeImBuf(ibuf);
 
@@ -1279,8 +1306,34 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
        }
 }
 
+/* note: currently used by proxy job for sequences, threading happens within sequence
+ * (different threads handles different frames, no threading within frame is needed)
+ */
+void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, struct MovieDistortion *distortion,
+                                              int cfra, int *build_sizes, int build_count, int undistorted)
+{
+       if (!build_count)
+               return;
+
+       if (ibuf) {
+               ImBuf *tmpibuf = ibuf;
+               int i;
+
+               if (undistorted)
+                       tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
+
+               for (i = 0; i < build_count; i++)
+                       movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, false);
+
+               if (tmpibuf != ibuf)
+                       IMB_freeImBuf(tmpibuf);
+       }
+}
+
 void BKE_movieclip_free(MovieClip *clip)
 {
+       BKE_sequencer_clear_movieclip_in_clipboard(clip);
+
        free_buffers(clip);
 
        BKE_tracking_free(&clip->tracking);
@@ -1325,7 +1378,7 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
                bConstraint *con;
 
                for (con = ob->constraints.first; con; con = con->next) {
-                       bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+                       bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
 
                        if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
                                bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
@@ -1365,3 +1418,14 @@ float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr)
 {
        return framenr + (float) clip->start_frame - 1.0f;
 }
+
+void BKE_movieclip_filename_for_frame(MovieClip *clip, int framenr, char *name)
+{
+       if (clip->source != MCLIP_SRC_MOVIE) {
+               get_sequence_fname(clip, framenr, name);
+       }
+       else {
+               BLI_strncpy(name, clip->name, FILE_MAX);
+               BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id));
+       }
+}