diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-03-15 20:57:19 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-03-15 20:57:19 +0400 |
commit | 08a8d11216053855460fdf54a88e33d88400a985 (patch) | |
tree | f562f129adfcde117cab6e33b48d9866386eb9d6 /source/blender/blenkernel | |
parent | bcec00dddcaedab7afbede3c4974b6c0cd1745c5 (diff) |
Further improvement for multi-threaded proxies
Handle sequences in a special case for dealing with
sequence sources.
Namely handle separate frames in separate threads,
but do disk read from a critical section since HDD
is not so friendly with lots threads requesting for
data from it.
Makes proxy building much faster than it was before.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_movieclip.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/movieclip.c | 51 |
2 files changed, 53 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 5777a4094bc..c8c94b2898b 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -64,9 +64,14 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUs void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion, int cfra, int *build_sizes, int build_count, int undistorted); +void BKE_movieclip_build_proxy_frame_for_ibuf(struct MovieClip *clip, struct ImBuf *ibuf, struct MovieDistortion *distortion, + int cfra, int *build_sizes, int build_count, int undistorted); + float BKE_movieclip_remap_scene_to_clip_frame(struct MovieClip *clip, float framenr); float BKE_movieclip_remap_clip_to_scene_frame(struct MovieClip *clip, float framenr); +void BKE_movieclip_filename_for_frame(struct MovieClip *clip, int framenr, char *name); + /* cacheing flags */ #define MOVIECLIP_CACHE_SKIP (1 << 0) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 1ad0bf1988c..e79754ca203 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1230,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; @@ -1244,7 +1244,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i scaleibuf = IMB_dupImBuf(ibuf); - IMB_scaleImBuf_threaded(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; @@ -1253,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); @@ -1264,6 +1271,9 @@ 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) { @@ -1287,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); @@ -1296,6 +1306,30 @@ 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); @@ -1384,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)); + } +} |