diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index dc65a2541b4..388843f8e70 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -958,11 +958,11 @@ class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel): sc = context.space_data clip = sc.clip - if clip: - layout.template_movieclip(sc, "clip", compact=True) - else: - layout.operator("clip.open", icon='FILESEL') - + col = layout.column() + col.template_movieclip(sc, "clip", compact=True) + col.prop(clip, "use_custom_start_frame") + if clip.use_custom_start_frame: + col.prop(clip, "start_frame") class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel): diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ccf64639967..a90fc28cd1e 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -153,9 +153,15 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name) BLI_strncpy(name, clip->name, sizeof(clip->name)); BLI_stringdec(name, head, tail, &numlen); - /* movieclips always points to first image from sequence, - * autoguess offset for now. could be something smarter in the future */ - offset = sequence_guess_offset(clip->name, strlen(head), numlen); + if (clip->flag & MCLIP_CUSTOM_START_FRAME) { + offset = clip->start_frame; + } + else { + /* movieclips always points to first image from sequence, + * autoguess offset for now. could be something smarter in the future + */ + offset = sequence_guess_offset(clip->name, strlen(head), numlen); + } if (numlen) BLI_stringenc(name, head, tail, numlen, offset + framenr - 1); @@ -250,6 +256,10 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in dur = IMB_anim_get_duration(clip->anim, tc); fra = framenr - 1; + if (clip->flag & MCLIP_CUSTOM_START_FRAME) { + fra += clip->start_frame - 1; + } + if (fra < 0) fra = 0; @@ -443,6 +453,8 @@ static MovieClip *movieclip_alloc(const char *name) IMB_TC_RECORD_RUN_NO_GAPS; clip->proxy.quality = 90; + clip->start_frame = 1; + return clip; } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 13e0a3c8b91..24b37bb041f 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -544,7 +544,10 @@ typedef struct SpaceClipDrawContext { struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ int image_width, image_height; /* image width and height for which texture was created */ unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - int framenr; + + /* fields to check if cache is still valid */ + int framenr, start_frame; + short custom_start_frame; } SpaceClipDrawContext; int ED_space_clip_texture_buffer_supported(SpaceClip *sc) @@ -574,6 +577,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) SpaceClipDrawContext *context = sc->draw_context; MovieClip *clip = ED_space_clip(sc); int need_rebind = 0; + short custom_start_frame = FALSE; context->last_texture = glaGetOneInteger(GL_TEXTURE_2D); @@ -583,6 +587,14 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) need_rebind |= context->texture_ibuf != ibuf; need_rebind |= context->framenr != sc->user.framenr; + if (clip->flag & MCLIP_CUSTOM_START_FRAME) { + need_rebind |= context->custom_start_frame != TRUE; + need_rebind |= context->start_frame != clip->start_frame; + } + else { + need_rebind |= context->custom_start_frame != FALSE; + } + if (need_rebind) { int width = ibuf->x, height = ibuf->y; int need_recreate = 0; @@ -636,6 +648,8 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->image_width = ibuf->x; context->image_height = ibuf->y; context->framenr = sc->user.framenr; + context->start_frame = clip->start_frame; + context->custom_start_frame = (clip->flag & MCLIP_CUSTOM_START_FRAME) ? TRUE : FALSE; } else { /* displaying exactly the same image which was loaded t oa texture, diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index f073a1957dc..81d532fd247 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -85,6 +85,8 @@ typedef struct MovieClip { int flag; int len; /* length of movie */ + + int start_frame, pad; } MovieClip; typedef struct MovieClipScopes { @@ -121,6 +123,7 @@ typedef struct MovieClipScopes { /* MovieClip->flag */ #define MCLIP_USE_PROXY (1<<0) #define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1) +#define MCLIP_CUSTOM_START_FRAME (1<<2) #define MCLIP_TIMECODE_FLAGS (MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR) diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 2cbe6946485..70cb0de643e 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -284,6 +284,19 @@ static void rna_def_movieclip(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); + + /* use custom offset */ + prop = RNA_def_property(srna, "use_custom_start_frame", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_CUSTOM_START_FRAME); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Custom Start Frame", "Use custom first frame offset instead of automatic frame number"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update"); + + /* frame offset */ + prop = RNA_def_property(srna, "start_frame", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "start_frame"); + RNA_def_property_ui_text(prop, "Start Frame", "Number of frame from sequence or movie displaying at scene frame #1"); + RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update"); } void RNA_def_movieclip(BlenderRNA *brna)