diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d61829891d6..3b40907244a 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -98,32 +98,50 @@ /* used by sequencer and image premul option - IMA_DO_PREMUL */ void converttopremul(struct ImBuf *ibuf) { - int x, y, val; - char *cp; + int x, y; if(ibuf==0) return; - if(ibuf->depth==24) { /* put alpha at 255 */ - - cp= (char *)(ibuf->rect); - for(y=0; yy; y++) { - for(x=0; xx; x++, cp+=4) { - cp[3]= 255; + if (ibuf->rect) { + int val; + char *cp; + if(ibuf->depth==24) { /* put alpha at 255 */ + cp= (char *)(ibuf->rect); + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + cp[3]= 255; + } + } + } else { + cp= (char *)(ibuf->rect); + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + val= cp[3]; + cp[0]= (cp[0]*val)>>8; + cp[1]= (cp[1]*val)>>8; + cp[2]= (cp[2]*val)>>8; + } } } - return; } - - cp= (char *)(ibuf->rect); - for(y=0; yy; y++) { - for(x=0; xx; x++, cp+=4) { - if(cp[3]==0) { - cp[0]= cp[1]= cp[2]= 0; + if (ibuf->rect_float) { + float val; + float *cp; + if(ibuf->depth==24) { /* put alpha at 1.0 */ + cp= ibuf->rect_float;; + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + cp[3]= 1.0; + } } - else if(cp[3]!=255) { - val= cp[3]; - cp[0]= (cp[0]*val)>>8; - cp[1]= (cp[1]*val)>>8; - cp[2]= (cp[2]*val)>>8; + } else { + cp= ibuf->rect_float; + for(y=0; yy; y++) { + for(x=0; xx; x++, cp+=4) { + val= cp[3]; + cp[0]= cp[0]*val; + cp[1]= cp[1]*val; + cp[2]= cp[2]*val; + } } } } diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index 42b30d6284f..8f5fb39d956 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -43,48 +43,55 @@ void IMB_flipy(struct ImBuf * ibuf) { - short x, y; - unsigned int *top, *bottom, do_float=0, *line; - float *topf=NULL, *bottomf=NULL, *linef=NULL; + int x, y; if (ibuf == NULL) return; - if (ibuf->rect == NULL) return; - - if (ibuf->rect_float) do_float =1; - x = ibuf->x; - y = ibuf->y; + if (ibuf->rect) { + unsigned int *top, *bottom, *line; - top = ibuf->rect; - bottom = top + ((y-1) * x); - line= MEM_mallocN(x*sizeof(int), "linebuf"); + x = ibuf->x; + y = ibuf->y; + + top = ibuf->rect; + bottom = top + ((y-1) * x); + line= MEM_mallocN(x*sizeof(int), "linebuf"); - if (do_float) { + y >>= 1; + + for(;y>0;y--) { + memcpy(line, top, x*sizeof(int)); + memcpy(top, bottom, x*sizeof(int)); + memcpy(bottom, line, x*sizeof(int)); + bottom -= x; + top+= x; + } + + MEM_freeN(line); + } + + if (ibuf->rect_float) { + float *topf=NULL, *bottomf=NULL, *linef=NULL; + + x = ibuf->x; + y = ibuf->y; + topf= ibuf->rect_float; bottomf = topf + 4*((y-1) * x); linef= MEM_mallocN(4*x*sizeof(float), "linebuff"); - } - y >>= 1; - for(;y>0;y--) { - - memcpy(line, top, x*sizeof(int)); - memcpy(top, bottom, x*sizeof(int)); - memcpy(bottom, line, x*sizeof(int)); - bottom -= x; - top+= x; - - if(do_float) { + y >>= 1; + + for(;y>0;y--) { memcpy(linef, topf, 4*x*sizeof(float)); memcpy(topf, bottomf, 4*x*sizeof(float)); memcpy(bottomf, linef, 4*x*sizeof(float)); bottomf -= 4*x; topf+= 4*x; } + + MEM_freeN(linef); } - - MEM_freeN(line); - if(linef) MEM_freeN(linef); } void IMB_flipx(struct ImBuf * ibuf) diff --git a/source/blender/include/BSE_seqeffects.h b/source/blender/include/BSE_seqeffects.h index 2962bbf3676..2dde9d3cc79 100644 --- a/source/blender/include/BSE_seqeffects.h +++ b/source/blender/include/BSE_seqeffects.h @@ -89,6 +89,7 @@ struct SeqEffectHandle { }; struct SeqEffectHandle get_sequence_effect(struct Sequence * seq); +struct SeqEffectHandle get_sequence_blend(struct Sequence * seq); int get_sequence_effect_num_inputs(int seq_type); void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force); diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 46e0aa6ff1f..3f86c6b163b 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -64,6 +64,9 @@ void reload_sequence_new_file(struct Sequence * seq); void sort_seq(void); void clear_scene_in_allseqs(struct Scene *sce); +char *give_seqname_by_type(int type); +char *give_seqname(struct Sequence *seq); + int evaluate_seq_frame(int cfra); struct StripElem *give_stripelem(struct Sequence *seq, int cfra); struct TStripElem *give_tstripelem(struct Sequence *seq, int cfra); diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index b401ee05433..066e23ca984 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -50,6 +50,7 @@ typedef struct StripElem { typedef struct TStripElem { struct ImBuf *ibuf; + struct ImBuf *ibuf_comp; struct TStripElem *se1, *se2, *se3; short ok; short pad; @@ -267,14 +268,17 @@ typedef struct SpeedControlVars { #define SEQ_TRANSFORM 27 #define SEQ_COLOR 28 #define SEQ_SPEED 29 +#define SEQ_EFFECT_MAX 29 #define STRIPELEM_FAILED 0 #define STRIPELEM_OK 1 #define STRIPELEM_META 2 #define SEQ_BLEND_REPLACE 0 -#define SEQ_BLEND_ALPHA_OVER 1 - +/* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical + to the table above. (Only those effects that handle _exactly_ two inputs, + otherwise, you can't really blend, right :) !) +*/ #endif diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 9bd2f9588a9..dda48a298ff 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -483,22 +483,40 @@ static void sound_panel_sound(bSound *sound) static char* seq_panel_blend_modes() { static char string[2048]; - char formatstring[2048]; - strcpy(formatstring, "Blend mode: %%t|%s %%x%d|%s %%x%d"); - sprintf(string, formatstring, - "REPLACE", SEQ_BLEND_REPLACE, - "TODO: ALPHA OVER", SEQ_BLEND_ALPHA_OVER); - return string; + Sequence *last_seq = get_last_seq(); + sprintf(string, "Blend mode: %%t|%s %%x%d", + "Replace", SEQ_BLEND_REPLACE); + + /* + Blending can only work without effect strips. + Otherwise, one would have + to decide, what the effect strips IPO should do: + - drive the effect _or_ + - drive the blend mode ? + + Also: effectdata is used by these implicit effects, + so that would collide also. + */ + + if (!(last_seq->type & SEQ_EFFECT)) { + int i; + + for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) { + if (get_sequence_effect_num_inputs(i) == 2) { + sprintf(string + strlen(string), + "|%s %%x%d", + give_seqname_by_type(i), i); + } + } + } + return string; } static void seq_panel_editing() { Sequence *last_seq = get_last_seq(); - char * seq_names[] = { "Image", "Meta", "Scene", "Movie", - "Snd RAM", "Snd HD", - "", "Effect" }; uiBlock *block; static char strdata[1024]; char * str = strdata; @@ -512,8 +530,7 @@ static void seq_panel_editing() 10, 230, 318, 204) == 0) return; uiDefBut(block, LABEL, - 0, (last_seq->type >= SEQ_EFFECT) ? - "Effect" : seq_names[last_seq->type], + 0, give_seqname(last_seq), 10,140,60,19, 0, 0, 0, 0, 0, ""); @@ -575,11 +592,13 @@ static void seq_panel_editing() uiDefButI(block, NUM, B_SEQ_BUT_TRANSFORM, "Start-Ofs", 10, 60, 120, 20, &last_seq->startofs, - 0.0, last_seq->len, 0.0, 0.0, "Start offset"); + 0.0, last_seq->len - last_seq->endofs, + 0.0, 0.0, "Start offset"); uiDefButI(block, NUM, B_SEQ_BUT_TRANSFORM, "End-Ofs", 130, 60, 120, 19, &last_seq->endofs, - 0.0, last_seq->len, 0.0, 0.0, "End offset"); + 0.0, last_seq->len - last_seq->startofs, + 0.0, 0.0, "End offset"); } } @@ -672,16 +691,20 @@ static void seq_panel_input() { Sequence *last_seq = get_last_seq(); uiBlock *block; + block = uiNewBlock(&curarea->uiblocks, "seq_panel_input", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Input", "Sequencer", 10, 230, 318, 204) == 0) return; - uiDefBut(block, TEX, - B_SEQ_BUT_RELOAD_FILE, "Dir: ", - 10,140,240,19, last_seq->strip->dir, - 0.0, 160.0, 100, 0, ""); + if (last_seq->type == SEQ_MOVIE + || last_seq->type == SEQ_IMAGE) { + uiDefBut(block, TEX, + B_SEQ_BUT_RELOAD_FILE, "Dir: ", + 10,140,240,19, last_seq->strip->dir, + 0.0, 160.0, 100, 0, ""); + } if (last_seq->type == SEQ_IMAGE) { StripElem * se = give_stripelem(last_seq, CFRA); @@ -702,73 +725,89 @@ static void seq_panel_input() 0.0, 80.0, 100, 0, ""); } - uiDefButBitI(block, TOG, SEQ_USE_CROP, - B_SEQ_BUT_RELOAD, "Use Crop", - 10,100,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Crop image before processing."); + if (last_seq->type == SEQ_MOVIE + || last_seq->type == SEQ_IMAGE + || last_seq->type == SEQ_SCENE) { + uiDefButBitI(block, TOG, SEQ_USE_CROP, + B_SEQ_BUT_RELOAD, "Use Crop", + 10,100,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Crop image before processing."); - if (last_seq->flag & SEQ_USE_CROP) { - if (!last_seq->strip->crop) { - last_seq->strip->crop = - MEM_callocN(sizeof(struct StripCrop), - "StripCrop"); + if (last_seq->flag & SEQ_USE_CROP) { + if (!last_seq->strip->crop) { + last_seq->strip->crop = + MEM_callocN(sizeof(struct StripCrop), + "StripCrop"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Top", + 10, 80, 120, 20, + &last_seq->strip->crop->top, + 0.0, 4096, 0.0, 0.0, "Top of source image"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Bottom", + 130, 80, 120, 20, + &last_seq->strip->crop->bottom, + 0.0, 4096, 0.0, 0.0, + "Bottom of source image"); + + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Left", + 10, 60, 120, 20, + &last_seq->strip->crop->left, + 0.0, 4096, 0.0, 0.0, "Left"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Right", + 130, 60, 120, 19, + &last_seq->strip->crop->right, + 0.0, 4096, 0.0, 0.0, "Right"); + } + + uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, + B_SEQ_BUT_RELOAD, "Use Translate", + 10,40,240,19, &last_seq->flag, + 0.0, 1.0, 0, 0, + "Translate image before processing."); + + if (last_seq->flag & SEQ_USE_TRANSFORM) { + if (!last_seq->strip->transform) { + last_seq->strip->transform = + MEM_callocN( + sizeof(struct StripTransform), + "StripTransform"); + } + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "X-Ofs", + 10, 20, 120, 20, + &last_seq->strip->transform->xofs, + 0.0, 4096, 0.0, 0.0, "X Offset"); + uiDefButI(block, NUM, + B_SEQ_BUT_RELOAD, "Y-Ofs", + 130, 20, 120, 20, + &last_seq->strip->transform->yofs, + 0.0, 4096, 0.0, 0.0, "Y Offset"); } - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Top", - 10, 80, 120, 20, &last_seq->strip->crop->top, - 0.0, 4096, 0.0, 0.0, "Top of source image"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Bottom", - 130, 80, 120, 20, &last_seq->strip->crop->bottom, - 0.0, 4096, 0.0, 0.0, "Bottom of source image"); - - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Left", - 10, 60, 120, 20, &last_seq->strip->crop->left, - 0.0, 4096, 0.0, 0.0, "Left"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Right", - 130, 60, 120, 19, &last_seq->strip->crop->right, - 0.0, 4096, 0.0, 0.0, "Right"); } - uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM, - B_SEQ_BUT_RELOAD, "Use Translate", - 10,40,240,19, &last_seq->flag, - 0.0, 1.0, 0, 0, - "Translate image before processing."); - - if (last_seq->flag & SEQ_USE_TRANSFORM) { - if (!last_seq->strip->transform) { - last_seq->strip->transform = - MEM_callocN(sizeof(struct StripTransform), - "StripTransform"); - } - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "X-Ofs", - 10, 20, 120, 20, &last_seq->strip->transform->xofs, - 0.0, 4096, 0.0, 0.0, "X Offset"); - uiDefButI(block, NUM, - B_SEQ_BUT_RELOAD, "Y-Ofs", - 130, 20, 120, 20, &last_seq->strip->transform->yofs, - 0.0, 4096, 0.0, 0.0, "Y Offset"); - } - - uiDefButI(block, NUM, B_SEQ_BUT_RELOAD_FILE, "A-Start", 10, 0, 120, 20, &last_seq->anim_startofs, - 0.0, MAXFRAMEF, 0.0, 0.0, "Animation start offset in file"); + 0.0, last_seq->len + last_seq->anim_startofs, 0.0, 0.0, + "Animation start offset in file"); uiDefButI(block, NUM, B_SEQ_BUT_RELOAD_FILE, "A-End", 130, 0, 120, 20, &last_seq->anim_endofs, - 0.0, MAXFRAMEF, 0.0, 0.0, "Animation end offset in file"); + 0.0, last_seq->len + last_seq->anim_endofs, 0.0, 0.0, + "Animation end offset in file"); - uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:", - 10, -20, 240,19, &last_seq->anim_preseek, - 0.0, 50.0, 100,0,"On MPEG-seeking preseek this many frames"); + if (last_seq->type == SEQ_MOVIE) { + uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:", + 10, -20, 240,19, &last_seq->anim_preseek, + 0.0, 50.0, 100,0, + "On MPEG-seeking preseek this many frames"); + } } diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 02f420dc641..2b301ab90c1 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -99,36 +99,6 @@ static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2) static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2); static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq, int outline_tint, float pixelx); -static char *give_seqname(Sequence *seq) -{ - if(seq->type==SEQ_META) return "Meta"; - else if(seq->type==SEQ_IMAGE) return "Image"; - else if(seq->type==SEQ_SCENE) return "Scene"; - else if(seq->type==SEQ_MOVIE) return "Movie"; - else if(seq->type==SEQ_RAM_SOUND) return "Audio (RAM)"; - else if(seq->type==SEQ_HD_SOUND) return "Audio (HD)"; - else if(seq->typestrip->dir; - else if(seq->type==SEQ_CROSS) return "Cross"; - else if(seq->type==SEQ_GAMCROSS) return "Gamma Cross"; - else if(seq->type==SEQ_ADD) return "Add"; - else if(seq->type==SEQ_SUB) return "Sub"; - else if(seq->type==SEQ_MUL) return "Mul"; - else if(seq->type==SEQ_ALPHAOVER) return "Alpha Over"; - else if(seq->type==SEQ_ALPHAUNDER) return "Alpha Under"; - else if(seq->type==SEQ_OVERDROP) return "Over Drop"; - else if(seq->type==SEQ_WIPE) return "Wipe"; - else if(seq->type==SEQ_GLOW) return "Glow"; - else if(seq->type==SEQ_TRANSFORM) return "Transform"; - else if(seq->type==SEQ_COLOR) return "Color"; - else if(seq->type==SEQ_SPEED) return "Speed"; - else if(seq->type==SEQ_PLUGIN) { - if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && - seq->plugin && seq->plugin->doit) return seq->plugin->pname; - return "Plugin"; - } - else return "Effect"; - -} static void draw_cfra_seq(void) { glColor3ub(0x30, 0x90, 0x50); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 69d2a12ad7c..8fb5ba6cf2a 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3560,14 +3560,13 @@ int play_anim(int mode) /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */ curarea->win_swap= WIN_BACK_OK; screen_swapbuffers(); - + while(TRUE) { if (U.uiflag & USER_SHOW_FPS) lredrawtime = PIL_check_seconds_timer(); while(qtest()) { - /* we test events first because of MKEY event */ event= extern_qread(&val); @@ -3588,7 +3587,7 @@ int play_anim(int mode) if(val) add_marker(CFRA-1); } } - if(ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break; + if(val && ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break; inner_play_anim_loop(0, 0); diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 82c897236a2..8d75090d911 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -1099,7 +1099,7 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname else if(blocktype==ID_SEQ) { Sequence *last_seq = get_last_seq(); - if(last_seq && ((last_seq->type & SEQ_EFFECT)||(last_seq->type == SEQ_HD_SOUND)||(last_seq->type == SEQ_RAM_SOUND))) { + if(last_seq) { *from= (ID *)last_seq; *ipo= last_seq->ipo; } @@ -1908,15 +1908,11 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char { Sequence *seq= (Sequence *)from; /* note, sequence is mimicing Id */ - if((seq->type & SEQ_EFFECT)|| - (seq->type == SEQ_RAM_SOUND)|| - (seq->type == SEQ_HD_SOUND)) { - if(seq->ipo==NULL) { - seq->ipo= add_ipo("SeqIpo", ID_SEQ); - } - update_seq_ipo_rect(seq); - return seq->ipo; + if(seq->ipo==NULL) { + seq->ipo= add_ipo("SeqIpo", ID_SEQ); } + update_seq_ipo_rect(seq); + return seq->ipo; } break; case ID_CU: diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 887737e0dad..dd31ebaad5d 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -946,6 +946,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) seq->start= cfra; seq->machine= machine; seq->mul= 1.0; + seq->blend_opacity = 100.0; return seq; } diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c index 5ed7ea29e2f..0099e5b9860 100644 --- a/source/blender/src/seqeffects.c +++ b/source/blender/src/seqeffects.c @@ -3014,7 +3014,27 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type) struct SeqEffectHandle get_sequence_effect(Sequence * seq) { - struct SeqEffectHandle rval = get_sequence_effect_impl(seq->type); + struct SeqEffectHandle rval; + + if (seq->type & SEQ_EFFECT) { + rval = get_sequence_effect_impl(seq->type); + } + + if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { + rval.load(seq); + seq->flag &= ~SEQ_EFFECT_NOT_LOADED; + } + + return rval; +} + +struct SeqEffectHandle get_sequence_blend(Sequence * seq) +{ + struct SeqEffectHandle rval; + + if (seq->blend_mode != 0) { + rval = get_sequence_effect_impl(seq->blend_mode); + } if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) { rval.load(seq); @@ -3028,5 +3048,9 @@ int get_sequence_effect_num_inputs(int seq_type) { struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type); - return rval.num_inputs(); + int cnt = rval.num_inputs(); + if (rval.execute) { + return cnt; + } + return 0; } diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 3d7ac3021a1..ba5052350ac 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -87,10 +87,14 @@ void free_tstripdata(int len, TStripElem *se) } for(a=0; aibuf && se->ok != STRIPELEM_META) { + if(se->ibuf) { IMB_freeImBuf(se->ibuf); se->ibuf = 0; } + if(se->ibuf_comp) { + IMB_freeImBuf(se->ibuf_comp); + se->ibuf_comp = 0; + } } MEM_freeN(seo); @@ -380,7 +384,7 @@ void reload_sequence_new_file(Sequence * seq) char str[FILE_MAXDIR+FILE_MAXFILE]; if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE || - seq->type == SEQ_HD_SOUND)) { + seq->type == SEQ_HD_SOUND || seq->type == SEQ_SCENE)) { return; } @@ -421,6 +425,14 @@ void reload_sequence_new_file(Sequence * seq) seq->strip->len = seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS); + } else if (seq->type == SEQ_SCENE) { + seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1; + seq->len -= seq->anim_startofs; + seq->len -= seq->anim_endofs; + if (seq->len < 0) { + seq->len = 0; + } + seq->strip->len = seq->len; } @@ -497,6 +509,54 @@ void clear_scene_in_allseqs(Scene *sce) } } +char *give_seqname_by_type(int type) +{ + switch(type) { + case SEQ_META: return "Meta"; + case SEQ_IMAGE: return "Image"; + case SEQ_SCENE: return "Scene"; + case SEQ_MOVIE: return "Movie"; + case SEQ_RAM_SOUND: return "Audio (RAM)"; + case SEQ_HD_SOUND: return "Audio (HD)"; + case SEQ_CROSS: return "Cross"; + case SEQ_GAMCROSS: return "Gamma Cross"; + case SEQ_ADD: return "Add"; + case SEQ_SUB: return "Sub"; + case SEQ_MUL: return "Mul"; + case SEQ_ALPHAOVER: return "Alpha Over"; + case SEQ_ALPHAUNDER: return "Alpha Under"; + case SEQ_OVERDROP: return "Over Drop"; + case SEQ_WIPE: return "Wipe"; + case SEQ_GLOW: return "Glow"; + case SEQ_TRANSFORM: return "Transform"; + case SEQ_COLOR: return "Color"; + case SEQ_SPEED: return "Speed"; + default: + return 0; + } +} + +char *give_seqname(Sequence *seq) +{ + char * name = give_seqname_by_type(seq->type); + + if (!name) { + if(seq->typestrip->dir; + } else if(seq->type==SEQ_PLUGIN) { + if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && + seq->plugin && seq->plugin->doit) { + return seq->plugin->pname; + } else { + return "Plugin"; + } + } else { + return "Effect"; + } + } + return name; +} + /* ***************** DO THE SEQUENCE ***************** */ static void make_black_ibuf(ImBuf *ibuf) @@ -561,7 +621,7 @@ static void multibuf(ImBuf *ibuf, float fmul) } } -static void do_effect(int cfra, Sequence *seq, TStripElem *se) +static void do_effect(int cfra, Sequence *seq, TStripElem * se) { TStripElem *se1, *se2, *se3; float fac, facf; @@ -587,7 +647,8 @@ static void do_effect(int cfra, Sequence *seq, TStripElem *se) early_out = sh.early_out(seq, fac, facf); if (early_out == -1) { /* no input needed */ - sh.execute(seq, cfra, fac, facf, se->ibuf->x, se->ibuf->y, + sh.execute(seq, cfra, fac, facf, + se->ibuf->x, se->ibuf->y, 0, 0, 0, se->ibuf); return; } @@ -751,7 +812,7 @@ static int evaluate_seq_frame_gen( Sequence *seq; int totseq=0; - memset(seq_arr, 0, sizeof(Sequence*) * MAXSEQ); + memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1)); seq= seqbase->first; while(seq) { @@ -777,59 +838,66 @@ int evaluate_seq_frame(int cfra) } -Sequence *get_shown_sequence(ListBase * seqbasep, int cfra, int chanshown) +static int video_seq_is_rendered(Sequence * seq) +{ + return (seq + && !(seq->flag & SEQ_MUTE) + && seq->type != SEQ_RAM_SOUND + && seq->type != SEQ_HD_SOUND); +} + +static int get_shown_sequences( + ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out) { - Sequence *seq, *seqim, *seqeff; Sequence *seq_arr[MAXSEQ+1]; - int b; + int b = chanshown; + int cnt = 0; - seq = 0; - - if (chanshown > MAXSEQ) { + if (b > MAXSEQ) { return 0; } if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) { - if (chanshown > 0) { - return seq_arr[chanshown]; - } - - /* we take the upper effect strip or - the lowest imagestrip/metastrip */ - seqim= seqeff= 0; - - for(b=1; bflag & SEQ_MUTE) { - /* skip */ - } else if(seq->type & SEQ_EFFECT) { - if(seqeff==0) seqeff= seq; - else if(seqeff->machine < seq->machine) - seqeff= seq; - } else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) { - if(seqim==0) seqim= seq; - else if(seqim->machine > seq->machine) - seqim= seq; + if (b > 0) { + if (seq_arr[b] == 0) { + return 0; + } + } else { + for (b = MAXSEQ; b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + break; } } } - if(seqeff) seq= seqeff; - else if(seqim) seq= seqim; - else seq= 0; } - return seq; + chanshown = b; + + for (;b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) { + break; + } + } + } + + for (;b <= chanshown; b++) { + if (video_seq_is_rendered(seq_arr[b])) { + seq_arr_out[cnt++] = seq_arr[b]; + } + } + + return cnt; } -static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra) +static int get_shown_seq_from_metastrip(Sequence * seqm, int cfra, + Sequence ** seq_arr_out) { - return get_shown_sequence(&seqm->seqbase, cfra, 0); + return get_shown_sequences(&seqm->seqbase, cfra, 0, seq_arr_out); } void set_meta_stripdata(Sequence *seqm) { - Sequence *seq; TStripElem *se; int a, cfra; @@ -847,10 +915,13 @@ void set_meta_stripdata(Sequence *seqm) /* sets all ->se1 pointers in stripdata, to read the ibuf from it */ for(a=0; alen; a++, se++) { + int cnt; + Sequence *seq_arr[MAXSEQ+1]; + cfra= a+seqm->start; - seq = get_shown_seq_from_metastrip(seqm, cfra); - if (seq) { - se->se1= give_tstripelem(seq, cfra); + cnt = get_shown_seq_from_metastrip(seqm, cfra, seq_arr); + if (cnt) { + se->se1= give_tstripelem(seq_arr[cnt-1], cfra); } else { se->se1= 0; } @@ -875,6 +946,8 @@ void set_meta_stripdata(Sequence *seqm) static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) { + float mul; + seq->strip->orx= se->ibuf->x; seq->strip->ory= se->ibuf->y; @@ -946,8 +1019,16 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) if(seq->mul == 0.0) { seq->mul = 1.0; } - if(seq->mul != 1.0) { - multibuf(se->ibuf, seq->mul); + + mul = seq->mul; + + if(seq->blend_mode == SEQ_BLEND_REPLACE + && seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq, cfra); + mul *= seq->facf0; + } + if(mul != 1.0) { + multibuf(se->ibuf, mul); } if(seq->flag & SEQ_MAKE_PREMUL) { @@ -968,40 +1049,66 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) } } -static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); +/* test if image too small or discarded from cache: reload */ + +static void test_and_auto_discard_ibuf(TStripElem * se) +{ + if (se->ibuf) { + if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty + || !(se->ibuf->rect || se->ibuf->rect_float)) { + IMB_freeImBuf(se->ibuf); + + se->ibuf= 0; + se->ok= STRIPELEM_OK; + } + } + if (se->ibuf_comp) { + if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty + || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) { + IMB_freeImBuf(se->ibuf_comp); + + se->ibuf_comp = 0; + } + } +} + +static TStripElem* do_build_seq_array_recursively( + ListBase *seqbasep, int cfra, int chanshown); static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) { char name[FILE_MAXDIR+FILE_MAXFILE]; - if (seq->type != SEQ_META && se->ibuf) { - /* test if image too small - or discarded from cache: reload */ - if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - se->ok= STRIPELEM_OK; - } + + if (seq->type != SEQ_META) { + test_and_auto_discard_ibuf(se); } if(seq->type == SEQ_META) { if(seq->seqbase.first) { - Sequence * seqmshown= - get_shown_seq_from_metastrip(seq, cfra); - if (seqmshown) { - if(cfra< seq->start) - do_build_seq_recursively(seqmshown, seq->start); - else if(cfra> seq->start+seq->len-1) - do_build_seq_recursively(seqmshown, seq->start + seq->len-1); - else do_build_seq_recursively(seqmshown, cfra); + if(cfra < seq->start) { + do_build_seq_array_recursively( + &seq->seqbase, + seq->start, 0); + } else if(cfra > seq->start + seq->len - 1) { + do_build_seq_array_recursively( + &seq->seqbase, + seq->start + seq->len - 1, 0); + } else { + do_build_seq_array_recursively( + &seq->seqbase, + cfra, 0); } } se->ok = STRIPELEM_META; if(se->se1 == 0) set_meta_stripdata(seq); if(se->se1) { - se->ibuf= se->se1->ibuf; + if(se->ibuf) { + IMB_freeImBuf(se->ibuf); + } + se->ibuf = se->se1->ibuf_comp; + IMB_refImBuf(se->ibuf); } } else if(seq->type & SEQ_EFFECT) { /* should the effect be recalculated? */ @@ -1086,7 +1193,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) /* hrms, set_scene still needed? work on that... */ if(sce!=oldsce) set_scene_bg(sce); - RE_BlenderFrame(re, sce, seq->sfra + se->nr); + RE_BlenderFrame(re, sce, + seq->sfra+se->nr+seq->anim_startofs); if(sce!=oldsce) set_scene_bg(oldsce); /* UGLY WARNING, it is set to zero in RE_BlenderFrame */ @@ -1127,6 +1235,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra) } } +static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra); + static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra) { float fac, facf; @@ -1229,13 +1339,7 @@ static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra) if (cfra_left == cfra_right || (s->flags & SEQ_SPEED_BLEND) == 0) { - if(se->ibuf) { - if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty - || !(se->ibuf->rect || se->ibuf->rect_float)) { - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - } - } + test_and_auto_discard_ibuf(se); if (se->ibuf == NULL) { se1 = do_build_seq_recursively_impl( @@ -1333,6 +1437,171 @@ static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) } } +static TStripElem* do_build_seq_array_recursively( + ListBase *seqbasep, int cfra, int chanshown) +{ + Sequence* seq_arr[MAXSEQ+1]; + int count; + int i; + TStripElem* se = 0; + + count = get_shown_sequences(seqbasep, cfra, chanshown, &seq_arr); + + if (!count) { + return 0; + } + + se = give_tstripelem(seq_arr[count - 1], cfra); + + test_and_auto_discard_ibuf(se); + + if (se->ibuf_comp != 0) { + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); + return se; + } + + + if(count == 1) { + se = do_build_seq_recursively(seq_arr[0], cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + return se; + } + + + for (i = count - 1; i >= 0; i--) { + int early_out; + Sequence * seq = seq_arr[i]; + struct SeqEffectHandle sh; + + se = give_tstripelem(seq, cfra); + + test_and_auto_discard_ibuf(se); + + if (se->ibuf_comp != 0) { + break; + } + if (seq->blend_mode == SEQ_BLEND_REPLACE) { + do_build_seq_recursively(seq, cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf); + break; + } + + sh = get_sequence_blend(seq_arr[i]); + + seq->facf0 = seq->facf1 = 1.0; + + if(seq->ipo && seq->ipo->curve.first) { + do_seq_ipo(seq, cfra); + } + + if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1; + + seq->facf0 *= seq->blend_opacity / 100.0; + seq->facf1 *= seq->blend_opacity / 100.0; + + early_out = sh.early_out(seq, seq->facf0, seq->facf1); + + switch (early_out) { + case -1: + case 2: + do_build_seq_recursively(seq, cfra); + se->ibuf_comp = se->ibuf; + IMB_refImBuf(se->ibuf_comp); + break; + case 1: + if (i == 0) { + se->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + IMB_cache_limiter_insert(se->ibuf_comp); + IMB_cache_limiter_ref(se->ibuf_comp); + IMB_cache_limiter_touch(se->ibuf_comp); + } + break; + case 0: + do_build_seq_recursively(seq, cfra); + break; + } + + if (se->ibuf_comp) { + break; + } + } + + i++; + + for (; i < count; i++) { + Sequence * seq = seq_arr[i]; + struct SeqEffectHandle sh = get_sequence_blend(seq); + TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra); + TStripElem* se2 = give_tstripelem(seq_arr[i], cfra); + + int early_out = sh.early_out(seq, seq->facf0, seq->facf1); + switch (early_out) { + case 0: { + int x= se2->ibuf->x; + int y= se2->ibuf->y; + + if (se1->ibuf_comp->rect_float || + se2->ibuf->rect_float) { + se2->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rectfloat, 0); + } else { + se2->ibuf_comp = IMB_allocImBuf( + (short)seqrectx, (short)seqrecty, + 32, IB_rect, 0); + } + + + if (!se1->ibuf_comp->rect_float && + se2->ibuf_comp->rect_float) { + IMB_float_from_rect(se1->ibuf_comp); + } + if (!se2->ibuf->rect_float && + se2->ibuf_comp->rect_float) { + IMB_float_from_rect(se2->ibuf); + } + + if (!se1->ibuf_comp->rect && + !se2->ibuf_comp->rect_float) { + IMB_rect_from_float(se1->ibuf); + } + if (!se2->ibuf->rect && + !se2->ibuf_comp->rect_float) { + IMB_rect_from_float(se2->ibuf); + } + + sh.execute(seq, cfra, seq->facf0, seq->facf1, x, y, + se1->ibuf_comp, se2->ibuf, 0, + se2->ibuf_comp); + + IMB_cache_limiter_insert(se2->ibuf_comp); + IMB_cache_limiter_ref(se2->ibuf_comp); + IMB_cache_limiter_touch(se2->ibuf_comp); + + IMB_cache_limiter_unref(se1->ibuf_comp); + IMB_cache_limiter_unref(se2->ibuf); + + break; + } + case 1: { + se2->ibuf_comp = se1->ibuf; + IMB_refImBuf(se2->ibuf_comp); + + break; + } + } + se = se2; + } + + return se; +} + /* * returned ImBuf is refed! * you have to unref after usage! @@ -1340,7 +1609,6 @@ static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra) static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) { - Sequence *seqfirst=0; Editing *ed; int count; ListBase *seqbasep; @@ -1360,19 +1628,13 @@ static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown) seqrectx= rectx; /* bad bad global! */ seqrecty= recty; - seqfirst = get_shown_sequence(seqbasep, cfra, chanshown); - - if (!seqfirst) { - return 0; - } - - se = do_build_seq_recursively(seqfirst, cfra); + se = do_build_seq_array_recursively(seqbasep, cfra, chanshown); if(!se) { return 0; } - return se->ibuf; + return se->ibuf_comp; } ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra, @@ -1728,13 +1990,16 @@ ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown) static void free_imbuf_strip_elem(TStripElem *se) { - if (se->ibuf) { - if (se->ok != STRIPELEM_META && se->ibuf != 0) - IMB_freeImBuf(se->ibuf); - se->ibuf= 0; - se->ok= STRIPELEM_OK; - se->se1= se->se2= se->se3= 0; + if(se->ibuf) { + IMB_freeImBuf(se->ibuf); } + if(se->ibuf_comp) { + IMB_freeImBuf(se->ibuf_comp); + } + se->ibuf_comp = 0; + se->ibuf= 0; + se->ok= STRIPELEM_OK; + se->se1= se->se2= se->se3= 0; } static void free_anim_seq(Sequence *seq) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index bfb67b6a07d..81a5606d7c4 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4667,11 +4667,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case SPACEKEY: if (G.qual==0) { - if (sseq->mainb) { - play_anim(1); - } else { - add_sequence(-1); - } + add_sequence(-1); } break; case BKEY: @@ -4729,6 +4725,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) select_linked_seq( 0 ); } else if((G.qual==LR_CTRLKEY)) { /* Cut at current frame */ select_linked_seq( 2 ); + } else if ((G.qual==LR_SHIFTKEY)) { + if (last_seq) { + last_seq->flag ^= SEQ_LOCK; + doredraw = 1; + } } break; case YKEY: @@ -4740,17 +4741,14 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.qual==LR_ALTKEY) { un_meta(); break; /*dont redraw timeline etc */ - } else if((G.qual==0)){ - if ((last_seq) && - (last_seq->type == SEQ_RAM_SOUND - || last_seq->type == SEQ_HD_SOUND)) - { + } else if(G.qual == 0){ + make_meta(); + break; /*dont redraw timeline etc */ + } else if (G.qual==LR_SHIFTKEY) { + if (last_seq) { last_seq->flag ^= SEQ_MUTE; doredraw = 1; - } else { - make_meta(); } - break; /*dont redraw timeline etc */ } else if ((G.qual==(LR_CTRLKEY|LR_ALTKEY) )) { add_marker(CFRA); } else if ((G.qual==LR_CTRLKEY)) { diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 53bbfb3fb69..088d91f7418 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -749,7 +749,15 @@ int blenderqread(unsigned short event, short val) case BACKSPACEKEY: break; - + case SPACEKEY: + if (curarea && curarea->spacetype==SPACE_SEQ) { + SpaceSeq *sseq= curarea->spacedata.first; + if (G.qual==0 && sseq->mainb) { + play_anim(1); + return 0; + } + } + break; case AKEY: if(textediting==0 && textspace==0) { if ((G.qual==LR_ALTKEY) && (curarea && curarea->spacetype==SPACE_VIEW3D)) {