Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-03-25 19:32:15 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-03-25 19:32:15 +0400
commita5fe1de7f976cb5f8a277ccd8e0b8de5c43b761a (patch)
tree899acf64f47bf604076ca6eeaf9f816b215d77d7 /source/blender/editors/space_clip
parent7635de3fee5fbc3f49af74601397483717e40579 (diff)
Clip editor prefetching changes
Now prefetching happens from cursor up to scene end frame and then from cursor down to scene start frame. Also disabled prefetching for non-unidistorted proxies because of issues with timecodes (seek horribly fails in some cases). This seek need to be fixed since it's actually happens for manual timeline scrubbing as well, but that's another story..
Diffstat (limited to 'source/blender/editors/space_clip')
-rw-r--r--source/blender/editors/space_clip/clip_editor.c198
1 files changed, 146 insertions, 52 deletions
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 6d9c5b4ba46..05e05b95967 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -741,14 +741,16 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc)
typedef struct PrefetchJob {
MovieClip *clip;
- int start_frame, end_frame;
+ int start_frame, current_frame, end_frame;
short render_size, render_flag;
} PrefetchJob;
typedef struct PrefetchQueue {
- int current_frame, start_frame, end_frame;
+ int initial_frame, current_frame, start_frame, end_frame;
short render_size, render_flag;
+ short direction;
+
SpinLock spin;
short *stop;
@@ -828,19 +830,29 @@ static unsigned char *prefetch_read_file_to_memory(MovieClip *clip, int current_
/* find first uncached frame within prefetching frame range */
static int prefetch_find_uncached_frame(MovieClip *clip, int from_frame, int end_frame,
- short render_size, short render_flag)
+ short render_size, short render_flag, short direction)
{
int current_frame;
+ MovieClipUser user = {0};
- for (current_frame = from_frame; current_frame <= end_frame; current_frame++) {
- MovieClipUser user = {0};
+ user.render_size = render_size;
+ user.render_flag = render_flag;
- user.framenr = current_frame;
- user.render_size = render_size;
- user.render_flag = render_flag;
+ if (direction > 0) {
+ for (current_frame = from_frame; current_frame <= end_frame; current_frame++) {
+ user.framenr = current_frame;
- if (!BKE_movieclip_has_cached_frame(clip, &user))
- break;
+ if (!BKE_movieclip_has_cached_frame(clip, &user))
+ break;
+ }
+ }
+ else {
+ for (current_frame = from_frame; current_frame >= end_frame; current_frame--) {
+ user.framenr = current_frame;
+
+ if (!BKE_movieclip_has_cached_frame(clip, &user))
+ break;
+ }
}
return current_frame;
@@ -853,12 +865,23 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
unsigned char *mem = NULL;
BLI_spin_lock(&queue->spin);
- if (!*queue->stop && queue->current_frame <= queue->end_frame && check_prefetch_allowed()) {
+ if (!*queue->stop && check_prefetch_allowed() &&
+ IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame))
+ {
int current_frame;
- current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame,
- queue->render_size, queue->render_flag);
- if (current_frame <= queue->end_frame) {
+ if (queue->direction > 0) {
+ current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame,
+ queue->render_size, queue->render_flag, 1);
+ }
+ else {
+ current_frame = prefetch_find_uncached_frame(clip, queue->current_frame - 1, queue->start_frame,
+ queue->render_size, queue->render_flag, -1);
+ }
+
+ if (IN_RANGE_INCL(current_frame, queue->start_frame, queue->end_frame)) {
+ int frames_processed;
+
mem = prefetch_read_file_to_memory(clip, current_frame, queue->render_size,
queue->render_flag, size_r);
@@ -866,9 +889,22 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
queue->current_frame = current_frame;
+ if (queue->direction > 0) {
+ frames_processed = queue->current_frame - queue->initial_frame;
+ }
+ else {
+ frames_processed = (queue->end_frame - queue->initial_frame) +
+ (queue->initial_frame - queue->current_frame);
+ }
+
*queue->do_update = 1;
- *queue->progress = (float)(queue->current_frame - queue->start_frame) /
- (queue->end_frame - queue->start_frame);
+ *queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame);
+
+ /* switch direction if read frames from current up to scene end frames */
+ if (current_frame == queue->end_frame) {
+ queue->current_frame = queue->initial_frame;
+ queue->direction = -1;
+ }
}
}
BLI_spin_unlock(&queue->spin);
@@ -911,8 +947,9 @@ static void *do_prefetch_thread(void *data_v)
return NULL;
}
-static void start_prefetch_threads(MovieClip *clip, int start_frame, int end_frame, short render_size,
- short render_flag, short *stop, short *do_update, float *progress)
+static void start_prefetch_threads(MovieClip *clip, int start_frame, int current_frame, int end_frame,
+ short render_size, short render_flag, short *stop, short *do_update,
+ float *progress)
{
ListBase threads;
PrefetchQueue queue;
@@ -927,11 +964,13 @@ static void start_prefetch_threads(MovieClip *clip, int start_frame, int end_fra
/* initialize queue */
BLI_spin_init(&queue.spin);
- queue.current_frame = start_frame;
+ queue.current_frame = current_frame;
+ queue.initial_frame = current_frame;
queue.start_frame = start_frame;
queue.end_frame = end_frame;
queue.render_size = render_size;
queue.render_flag = render_flag;
+ queue.direction = 1;
queue.stop = stop;
queue.do_update = do_update;
@@ -962,45 +1001,70 @@ static void start_prefetch_threads(MovieClip *clip, int start_frame, int end_fra
MEM_freeN(handles);
}
-static void do_prefetch_movie(MovieClip *clip, int start_frame, int end_frame, short render_size,
- short render_flag, short *stop, short *do_update, float *progress)
+static bool prefetch_movie_frame(MovieClip *clip, int frame, short render_size,
+ short render_flag, short *stop)
{
- int current_frame;
-
- for (current_frame = start_frame; current_frame <= end_frame; current_frame++) {
- MovieClipUser user = {0};
- ImBuf *ibuf;
-
- if (!check_prefetch_allowed() || *stop)
- break;
+ MovieClipUser user = {0};
+ ImBuf *ibuf;
- user.framenr = current_frame;
- user.render_size = render_size;
- user.render_flag = render_flag;
+ if (!check_prefetch_allowed() || *stop)
+ return false;
- if (!BKE_movieclip_has_cached_frame(clip, &user)) {
- ibuf = BKE_movieclip_anim_ibuf_for_frame(clip, &user);
+ user.framenr = frame;
+ user.render_size = render_size;
+ user.render_flag = render_flag;
- if (ibuf) {
- int result;
+ if (!BKE_movieclip_has_cached_frame(clip, &user)) {
+ ibuf = BKE_movieclip_anim_ibuf_for_frame(clip, &user);
- result = BKE_movieclip_put_frame_if_possible(clip, &user, ibuf);
+ if (ibuf) {
+ int result;
- if (!result) {
- /* no more space in the cache, we could stop prefetching here */
- *stop = 1;
- }
+ result = BKE_movieclip_put_frame_if_possible(clip, &user, ibuf);
- IMB_freeImBuf(ibuf);
- }
- else {
- /* error reading frame, fair enough stop attempting further reading */
+ if (!result) {
+ /* no more space in the cache, we could stop prefetching here */
*stop = 1;
}
+
+ IMB_freeImBuf(ibuf);
}
+ else {
+ /* error reading frame, fair enough stop attempting further reading */
+ *stop = 1;
+ }
+ }
+
+ return true;
+}
+
+static void do_prefetch_movie(MovieClip *clip, int start_frame, int current_frame, int end_frame,
+ short render_size, short render_flag, short *stop, short *do_update,
+ float *progress)
+{
+ int frame;
+ int frames_processed = 0;
+
+ /* read frames starting from current frame up to scene end frame */
+ for (frame = current_frame; frame <= end_frame; frame++) {
+ if (!prefetch_movie_frame(clip, frame, render_size, render_flag, stop))
+ return;
+
+ frames_processed++;
+
+ *do_update = 1;
+ *progress = (float) frames_processed / (end_frame - start_frame);
+ }
+
+ /* read frames starting from current frame up to scene start frame */
+ for (frame = current_frame; frame >= start_frame; frame--) {
+ if (!prefetch_movie_frame(clip, frame, render_size, render_flag, stop))
+ return;
+
+ frames_processed++;
*do_update = 1;
- *progress = (float)(current_frame - start_frame) / (end_frame - start_frame);
+ *progress = (float) frames_processed / (end_frame - start_frame);
}
}
@@ -1010,13 +1074,13 @@ static void prefetch_startjob(void *pjv, short *stop, short *do_update, float *p
if (pj->clip->source == MCLIP_SRC_SEQUENCE) {
/* read sequence files in multiple threads */
- start_prefetch_threads(pj->clip, pj->start_frame, pj->end_frame,
+ start_prefetch_threads(pj->clip, pj->start_frame, pj->current_frame, pj->end_frame,
pj->render_size, pj->render_flag,
stop, do_update, progress);
}
else if (pj->clip->source == MCLIP_SRC_MOVIE) {
/* read movie in a single thread */
- do_prefetch_movie(pj->clip, pj->start_frame, pj->end_frame,
+ do_prefetch_movie(pj->clip, pj->start_frame, pj->current_frame, pj->end_frame,
pj->render_size, pj->render_flag,
stop, do_update, progress);
}
@@ -1032,6 +1096,13 @@ static void prefetch_freejob(void *pjv)
MEM_freeN(pj);
}
+static int prefetch_get_start_frame(const bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ return SFRA;
+}
+
static int prefetch_get_final_frame(const bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -1059,6 +1130,20 @@ static bool prefetch_check_early_out(const bContext *C)
if (clip->prefetch_ok)
return true;
+ if (clip->source == MCLIP_SRC_MOVIE) {
+ /* for movies we only prefetch undistorted proxy,
+ * in other cases prefetching could lead to issues
+ * due to timecodes issues.
+ */
+
+ if (clip->flag & MCLIP_USE_PROXY) {
+ MovieClipUser *user = &sc->user;
+
+ if ((user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) == 0)
+ return true;
+ }
+ }
+
clip_len = BKE_movieclip_get_duration(clip);
/* check whether all the frames from prefetch range are cached */
@@ -1066,10 +1151,18 @@ static bool prefetch_check_early_out(const bContext *C)
first_uncached_frame =
prefetch_find_uncached_frame(clip, sc->user.framenr, end_frame,
- sc->user.render_size, sc->user.render_flag);
+ sc->user.render_size, sc->user.render_flag, 1);
- if (first_uncached_frame > end_frame || first_uncached_frame == clip_len)
- return true;
+ if (first_uncached_frame > end_frame || first_uncached_frame == clip_len) {
+ int start_frame = prefetch_get_start_frame(C);
+
+ first_uncached_frame =
+ prefetch_find_uncached_frame(clip, sc->user.framenr, start_frame,
+ sc->user.render_size, sc->user.render_flag, -1);
+
+ if (first_uncached_frame < start_frame)
+ return true;
+ }
return false;
}
@@ -1101,7 +1194,8 @@ void clip_start_prefetch_job(const bContext *C)
/* create new job */
pj = MEM_callocN(sizeof(PrefetchJob), "prefetch job");
pj->clip = ED_space_clip_get_clip(sc);
- pj->start_frame = sc->user.framenr;
+ pj->start_frame = prefetch_get_start_frame(C);
+ pj->current_frame = sc->user.framenr;
pj->end_frame = prefetch_get_final_frame(C);
pj->render_size = sc->user.render_size;
pj->render_flag = sc->user.render_flag;