/* get memory buffer for first uncached frame within prefetch frame range */ static unsigned char *prefetch_thread_next_frame( PrefetchQueue *queue, MovieClip *clip, size_t *r_size, int *r_current_frame) { unsigned char *mem = NULL; BLI_spin_lock(&queue->spin); if (!*queue->stop && !check_prefetch_break() && IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame)) { int current_frame; if (queue->forward) { current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame, queue->render_size, queue->render_flag, 1); /* 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->forward = false; } } if (!queue->forward) { 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, r_size); *r_current_frame = current_frame; queue->current_frame = current_frame; if (queue->forward) { 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)frames_processed / (queue->end_frame - queue->start_frame); } } BLI_spin_unlock(&queue->spin); return mem; }
static bool prefetch_movie_frame(MovieClip *clip, int frame, short render_size, short render_flag, short *stop) { MovieClipUser user = {0}; ImBuf *ibuf; if (check_prefetch_break() || *stop) return false; user.framenr = frame; user.render_size = render_size; user.render_flag = render_flag; if (!BKE_movieclip_has_cached_frame(clip, &user)) { ibuf = BKE_movieclip_anim_ibuf_for_frame(clip, &user); if (ibuf) { int result; result = BKE_movieclip_put_frame_if_possible(clip, &user, ibuf); 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; }