Clip editor prefetch changes

Made it an operator instead of automatic prefetching.
Filling the whole memory with frames is not always
desired behavior.

Now prefetching is available via P-key, or from Clip
panel in toolbox or from Clip menu.

Also enabled prefetching for non-proxied movies.
This commit is contained in:
Sergey Sharybin 2013-04-04 09:50:38 +00:00
parent ef1af9f9c4
commit 845aea6864
9 changed files with 56 additions and 89 deletions

@ -886,6 +886,7 @@ class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
layout.operator("clip.set_viewport_background")
layout.operator("clip.setup_tracking_scene")
layout.operator("clip.prefetch")
class CLIP_MT_view(Menu):
@ -945,6 +946,7 @@ class CLIP_MT_clip(Menu):
layout.operator("clip.open")
if clip:
layout.operator("clip.prefetch")
layout.operator("clip.reload")
layout.menu("CLIP_MT_proxy")

@ -1168,7 +1168,6 @@ void BKE_movieclip_reload(MovieClip *clip)
free_buffers(clip);
clip->tracking.stabilization.ok = FALSE;
clip->prefetch_ok = FALSE;
/* update clip source */
detect_clip_source(clip);

@ -6588,8 +6588,6 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
clip->tracking.dopesheet.channels.first = clip->tracking.dopesheet.channels.last = NULL;
clip->tracking.dopesheet.coverage_segments.first = clip->tracking.dopesheet.coverage_segments.last = NULL;
clip->prefetch_ok = FALSE;
link_list(fd, &tracking->objects);
for (object = tracking->objects.first; object; object = object->next) {

@ -1456,8 +1456,6 @@ void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
if (ibuf) {
draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
IMB_freeImBuf(ibuf);
clip_start_prefetch_job(C);
}
else {
ED_region_grid_draw(ar, zoomx, zoomy);

@ -605,26 +605,9 @@ typedef struct PrefetchThread {
} PrefetchThread;
/* check whether pre-fetching is allowed */
static bool check_prefetch_allowed(void)
static bool check_prefetch_break(void)
{
wmWindowManager *wm;
/* if there's any job started, better to leave all CPU and
* HDD bandwidth to it
*
* also, display transform could be needed during playback,
* so better to avoid prefetching in this case and reserve
* all the power for display transform
*/
for (wm = G.main->wm.first; wm; wm = wm->id.next) {
if (WM_jobs_has_running_except(wm, WM_JOB_TYPE_CLIP_PREFETCH))
return false;
if (ED_screen_animation_playing(wm))
return false;
}
return true;
return G.is_break;
}
/* read file for specified frame number to the memory */
@ -706,7 +689,7 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
unsigned char *mem = NULL;
BLI_spin_lock(&queue->spin);
if (!*queue->stop && check_prefetch_allowed() &&
if (!*queue->stop && !check_prefetch_break() &&
IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame))
{
int current_frame;
@ -848,7 +831,7 @@ static bool prefetch_movie_frame(MovieClip *clip, int frame, short render_size,
MovieClipUser user = {0};
ImBuf *ibuf;
if (!check_prefetch_allowed() || *stop)
if (check_prefetch_break() || *stop)
return false;
user.framenr = frame;
@ -968,26 +951,6 @@ static bool prefetch_check_early_out(const bContext *C)
int first_uncached_frame, end_frame;
int clip_len;
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;
}
else {
return true;
}
}
clip_len = BKE_movieclip_get_duration(clip);
/* check whether all the frames from prefetch range are cached */
@ -1016,7 +979,6 @@ void clip_start_prefetch_job(const bContext *C)
wmJob *wm_job;
PrefetchJob *pj;
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
if (prefetch_check_early_out(C))
return;
@ -1024,17 +986,6 @@ void clip_start_prefetch_job(const bContext *C)
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_area(C), "Prefetching",
WM_JOB_PROGRESS, WM_JOB_TYPE_CLIP_PREFETCH);
if (WM_jobs_is_running(wm_job)) {
/* if job is already running, it'll call clip editor redraw when
* it's finished, so cache line is nicely updated
* this will also trigger call of this function, which will ensure
* all needed frames are prefetched
*/
return;
}
clip->prefetch_ok = true;
/* create new job */
pj = MEM_callocN(sizeof(PrefetchJob), "prefetch job");
pj->clip = ED_space_clip_get_clip(sc);
@ -1045,9 +996,11 @@ void clip_start_prefetch_job(const bContext *C)
pj->render_flag = sc->user.render_flag;
WM_jobs_customdata_set(wm_job, pj, prefetch_freejob);
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP, 0);
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | ND_DISPLAY, 0);
WM_jobs_callbacks(wm_job, prefetch_startjob, NULL, NULL, NULL);
G.is_break = FALSE;
/* and finally start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
}

@ -108,6 +108,8 @@ void CLIP_OT_mode_set(struct wmOperatorType *ot);
void CLIP_OT_view_ndof(struct wmOperatorType *ot);
void CLIP_OT_prefetch(struct wmOperatorType *ot);
/* clip_toolbar.c */
struct ARegion *ED_clip_has_properties_region(struct ScrArea *sa);
void CLIP_OT_tools(struct wmOperatorType *ot);

@ -1378,6 +1378,47 @@ void CLIP_OT_view_ndof(wmOperatorType *ot)
ot->invoke = clip_view_ndof_invoke;
}
/********************** Prefetch operator *********************/
static int clip_prefetch_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_CLIP_PREFETCH))
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
/* running render */
switch (event->type) {
case ESCKEY:
return OPERATOR_RUNNING_MODAL;
break;
}
return OPERATOR_PASS_THROUGH;
}
static int clip_prefetch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
{
clip_start_prefetch_job(C);
/* add modal handler for ESC */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
void CLIP_OT_prefetch(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Prefetch Frames";
ot->idname = "CLIP_OT_prefetch";
ot->description = "Prefetch frames from disk for faster playback/tracking";
/* api callbacks */
ot->poll = ED_space_clip_view_clip_poll;
ot->invoke = clip_prefetch_invoke;
ot->modal = clip_prefetch_modal;
}
/********************** macroses *********************/
void ED_operatormacros_clip(void)

@ -236,16 +236,6 @@ static void clip_stabilization_tag_refresh(ScrArea *sa)
}
}
static void clip_prefetch_tag_refresh(ScrArea *sa)
{
SpaceClip *sc = (SpaceClip *) sa->spacedata.first;
MovieClip *clip = ED_space_clip_get_clip(sc);
if (clip) {
clip->prefetch_ok = FALSE;
}
}
/* ******************** default callbacks for clip space ***************** */
static SpaceLink *clip_new(const bContext *C)
@ -358,7 +348,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
switch (wmn->data) {
case ND_FRAME:
clip_scopes_tag_refresh(sa);
clip_prefetch_tag_refresh(sa);
/* no break! */
case ND_FRAME_RANGE:
@ -367,19 +356,11 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
}
break;
case NC_MOVIECLIP:
if (wmn->data == 0 && wmn->action == 0) {
/* a nit funky, happens from prefetch job to update
* cache line and job progress
*/
ED_area_tag_redraw(sa);
}
switch (wmn->data) {
case ND_DISPLAY:
case ND_SELECT:
clip_scopes_tag_refresh(sa);
ED_area_tag_redraw(sa);
clip_prefetch_tag_refresh(sa);
break;
}
switch (wmn->action) {
@ -423,7 +404,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
case NC_SCREEN:
switch (wmn->data) {
case ND_ANIMPLAY:
clip_prefetch_tag_refresh(sa);
ED_area_tag_redraw(sa);
break;
}
@ -432,7 +412,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
if (wmn->data == ND_SPACE_CLIP) {
clip_scopes_tag_refresh(sa);
clip_stabilization_tag_refresh(sa);
clip_prefetch_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
break;
@ -442,10 +421,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
ED_area_tag_redraw(sa);
}
break;
case NC_WM:
if (wmn->data == ND_FILEREAD)
clip_prefetch_tag_refresh(sa);
break;
}
}
@ -465,6 +440,7 @@ static void clip_operatortypes(void)
WM_operatortype_append(CLIP_OT_rebuild_proxy);
WM_operatortype_append(CLIP_OT_mode_set);
WM_operatortype_append(CLIP_OT_view_ndof);
WM_operatortype_append(CLIP_OT_prefetch);
/* ** clip_toolbar.c ** */
WM_operatortype_append(CLIP_OT_tools);
@ -598,6 +574,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "CLIP_OT_set_solver_keyframe", EKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "keyframe", 1);
/* io/playback */
WM_keymap_add_item(keymap, "CLIP_OT_prefetch", PKEY, KM_PRESS, 0, 0);
/* ******** Hotkeys avalaible for main region only ******** */
keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);

@ -98,11 +98,6 @@ typedef struct MovieClip {
/* color management */
ColorManagedColorspaceSettings colorspace_settings;
/* runtime prefetching stuff */
char prefetch_ok;
char pad[7];
} MovieClip;
typedef struct MovieClipScopes {