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:
Diffstat (limited to 'source/blender/blenkernel/intern/sequencer.c')
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2259
1 files changed, 972 insertions, 1287 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 790087334c6..b6bb5c3a51b 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -39,7 +39,9 @@
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
+#include "DNA_sound_types.h"
+#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -49,10 +51,12 @@
#include "RNA_access.h"
#include "RE_pipeline.h"
+#include "BLI_math.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BLI_threads.h"
#include <pthread.h>
#include "IMB_imbuf.h"
@@ -69,8 +73,6 @@
#endif
/* **** XXX ******** */
-static int seqrectx= 0; /* bad bad global! */
-static int seqrecty= 0;
//static void waitcursor(int val) {}
//static int blender_test_break() {return 0;}
@@ -88,71 +90,38 @@ void printf_strip(Sequence *seq)
fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
}
-void seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
+int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
{
Sequence *iseq;
for(iseq= seqbase->first; iseq; iseq= iseq->next) {
- seq_recursive_apply(iseq, apply_func, arg);
+ if(seq_recursive_apply(iseq, apply_func, arg) == -1)
+ return -1; /* bail out */
}
+ return 1;
}
-void seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
+int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
{
- if(apply_func(seq, arg) && seq->seqbase.first)
- seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
+ int ret= apply_func(seq, arg);
+
+ if(ret == -1)
+ return -1; /* bail out */
+
+ if(ret && seq->seqbase.first)
+ ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
+
+ return ret;
}
/* **********************************************************************
alloc / free functions
********************************************************************** */
-static void free_tstripdata(int len, TStripElem *se)
-{
- TStripElem *seo;
- int a;
-
- seo= se;
- if (!se)
- return;
-
- for(a=0; a<len; a++, se++) {
- 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);
-}
void new_tstripdata(Sequence *seq)
{
if(seq->strip) {
- free_tstripdata(seq->strip->len, seq->strip->tstripdata);
- free_tstripdata(seq->strip->endstill,
- seq->strip->tstripdata_endstill);
- free_tstripdata(seq->strip->startstill,
- seq->strip->tstripdata_startstill);
-
- seq->strip->tstripdata= 0;
- seq->strip->tstripdata_endstill= 0;
- seq->strip->tstripdata_startstill= 0;
-
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
seq->strip->len= seq->len;
}
}
@@ -198,23 +167,11 @@ void seq_free_strip(Strip *strip)
MEM_freeN(strip->color_balance);
}
- free_tstripdata(strip->len, strip->tstripdata);
- free_tstripdata(strip->endstill, strip->tstripdata_endstill);
- free_tstripdata(strip->startstill, strip->tstripdata_startstill);
-
- if(strip->ibuf_startstill) {
- IMB_freeImBuf(strip->ibuf_startstill);
- strip->ibuf_startstill = 0;
- }
-
- if(strip->ibuf_endstill) {
- IMB_freeImBuf(strip->ibuf_endstill);
- strip->ibuf_endstill = 0;
- }
-
MEM_freeN(strip);
}
+static void seq_free_animdata(Scene *scene, Sequence *seq);
+
void seq_free_sequence(Scene *scene, Sequence *seq)
{
if(seq->strip) seq_free_strip(seq->strip);
@@ -236,6 +193,8 @@ void seq_free_sequence(Scene *scene, Sequence *seq)
if(seq->scene_sound)
sound_remove_scene_sound(scene, seq->scene_sound);
+
+ seq_free_animdata(scene, seq);
}
MEM_freeN(seq);
@@ -504,6 +463,31 @@ void calc_sequence_disp(Scene *scene, Sequence *seq)
seq_update_sound(scene, seq);
}
+static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+{
+ Sequence *seq;
+
+ /* for sound we go over full meta tree to update bounds of the sound strips,
+ since sound is played outside of evaluating the imbufs, */
+ for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+ else if((seq->type == SEQ_SOUND) || (seq->type == SEQ_SCENE)) {
+ if(seq->scene_sound) {
+ int startofs = seq->startofs;
+ int endofs = seq->endofs;
+ if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
+ startofs = metaseq->start + metaseq->startofs - seq->start;
+
+ if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
+ endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
+ sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
+ }
+ }
+ }
+}
+
void calc_sequence(Scene *scene, Sequence *seq)
{
Sequence *seqm;
@@ -547,8 +531,8 @@ void calc_sequence(Scene *scene, Sequence *seq)
if(seq->type==SEQ_META) {
seqm= seq->seqbase.first;
if(seqm) {
- min= 1000000;
- max= -1000000;
+ min= MAXFRAME * 2;
+ max= -MAXFRAME * 2;
while(seqm) {
if(seqm->startdisp < min) min= seqm->startdisp;
if(seqm->enddisp > max) max= seqm->enddisp;
@@ -563,14 +547,18 @@ void calc_sequence(Scene *scene, Sequence *seq)
new_tstripdata(seq);
}
}
+ seq_update_sound_bounds_recursive(scene, seq);
}
calc_sequence_disp(scene, seq);
}
}
-void reload_sequence_new_file(Scene *scene, Sequence * seq)
+/* note: caller should run calc_sequence(scene, seq) after */
+void reload_sequence_new_file(Main *bmain, Scene *scene, Sequence * seq, int lock_range)
{
char str[FILE_MAXDIR+FILE_MAXFILE];
+ int prev_startdisp, prev_enddisp;
+ /* note: dont rename the strip, will break animation curves */
if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
seq->type == SEQ_SOUND ||
@@ -578,6 +566,14 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
return;
}
+ if(lock_range) {
+ /* keep so we dont have to move the actual start and end points (only the data) */
+ calc_sequence_disp(scene, seq);
+ prev_startdisp= seq->startdisp;
+ prev_enddisp= seq->enddisp;
+ }
+
+
new_tstripdata(seq);
if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
@@ -588,7 +584,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
if (seq->type == SEQ_IMAGE) {
/* Hack? */
- int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
+ size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
+
seq->len = olen;
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
@@ -623,7 +620,8 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
}
seq->strip->len = seq->len;
} else if (seq->type == SEQ_SCENE) {
- Scene * sce = G.main->scene.first;
+ /* 'seq->scenenr' should be replaced with something more reliable */
+ Scene * sce = bmain->scene.first;
int nr = 1;
while(sce) {
@@ -639,9 +637,6 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
} else {
sce = seq->scene;
}
-
- BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
- seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
seq->len -= seq->anim_startofs;
@@ -654,6 +649,12 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
free_proxy_seq(seq);
+ if(lock_range) {
+ seq_tx_set_final_left(seq, prev_startdisp);
+ seq_tx_set_final_right(seq, prev_enddisp);
+ seq_single_fix(seq);
+ }
+
calc_sequence(scene, seq);
}
@@ -709,12 +710,12 @@ static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
return 1;
}
-void clear_scene_in_allseqs(Scene *scene)
+void clear_scene_in_allseqs(Main *bmain, Scene *scene)
{
Scene *scene_iter;
/* when a scene is deleted: test all seqs */
- for(scene_iter= G.main->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
+ for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
if(scene_iter != scene && scene_iter->ed) {
seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
}
@@ -740,7 +741,7 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
Sequence *seq;
for(seq=seqbasep->first; seq; seq= seq->next) {
if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
- sprintf(sui->name_dest, "%.18s.%03d", sui->name_src, sui->count++);
+ sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */
sui->match= 1; /* be sure to re-scan */
}
}
@@ -761,12 +762,17 @@ void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
strcpy(sui.name_src, seq->name+2);
strcpy(sui.name_dest, seq->name+2);
+ sui.count= 1;
+ sui.match= 1; /* assume the worst to start the loop */
+
/* Strip off the suffix */
- if ((dot=strrchr(sui.name_src, '.')))
+ if ((dot=strrchr(sui.name_src, '.'))) {
*dot= '\0';
+ dot++;
- sui.count= 1;
- sui.match= 1; /* assume the worst to start the loop */
+ if(*dot)
+ sui.count= atoi(dot) + 1;
+ }
while(sui.match) {
sui.match= 0;
@@ -797,6 +803,7 @@ static char *give_seqname_by_type(int type)
case SEQ_GLOW: return "Glow";
case SEQ_TRANSFORM: return "Transform";
case SEQ_COLOR: return "Color";
+ case SEQ_MULTICAM: return "Multicam";
case SEQ_SPEED: return "Speed";
default:
return 0;
@@ -888,143 +895,16 @@ static void multibuf(ImBuf *ibuf, float fmul)
}
}
-static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
+static float give_stripelem_index(Sequence *seq, float cfra)
{
- TStripElem *se1, *se2, *se3;
- float fac, facf;
- int x, y;
- int early_out;
- struct SeqEffectHandle sh = get_sequence_effect(seq);
- FCurve *fcu= NULL;
-
- if (!sh.execute) { /* effect not supported in this version... */
- make_black_ibuf(se->ibuf);
- return;
- }
-
- if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
- sh.get_default_fac(seq, cfra, &fac, &facf);
- if( scene->r.mode & R_FIELDS ); else facf= fac;
- } else {
- fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
- "effect_fader", 0);
- if (fcu) {
- fac = facf = evaluate_fcurve(fcu, cfra);
- if( scene->r.mode & R_FIELDS ) {
- facf = evaluate_fcurve(fcu, cfra + 0.5);
- }
- } else {
- fac = facf = seq->effect_fader;
- }
- }
-
- early_out = sh.early_out(seq, fac, facf);
+ float nr;
- if (early_out == -1) { /* no input needed */
- sh.execute(scene, seq, cfra, fac, facf,
- se->ibuf->x, se->ibuf->y,
- 0, 0, 0, se->ibuf);
- return;
- }
-
- switch (early_out) {
- case 0:
- if (se->se1==0 || se->se2==0 || se->se3==0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se1= se->se1;
- se2= se->se2;
- se3= se->se3;
-
- if ( (se1==0 || se2==0 || se3==0)
- || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- break;
- case 1:
- if (se->se1 == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se1= se->se1;
-
- if (se1 == 0 || se1->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- if (se->ibuf != se1->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = se1->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- return;
- case 2:
- if (se->se2 == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se2= se->se2;
-
- if (se2 == 0 || se2->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
- if (se->ibuf != se2->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = se2->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- return;
- default:
- make_black_ibuf(se->ibuf);
- return;
- }
-
- x= se2->ibuf->x;
- y= se2->ibuf->y;
-
- if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se1->ibuf);
- }
- if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se2->ibuf);
- }
- if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se3->ibuf);
- }
-
- if (!se1->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se1->ibuf);
- }
- if (!se2->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se2->ibuf);
- }
- if (!se3->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se3->ibuf);
- }
-
- sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
- se->ibuf);
-}
-
-static int give_stripelem_index(Sequence *seq, int cfra)
-{
- int nr;
-
- if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
if(seq->len == 0) return -1;
if(seq->flag&SEQ_REVERSE_FRAMES) {
/*reverse frame in this sequence */
if(cfra <= seq->start) nr= seq->len-1;
else if(cfra >= seq->start+seq->len-1) nr= 0;
- else nr= (seq->start + seq->len) - cfra;
+ else nr= (seq->start + seq->len - 1) - cfra;
} else {
if(cfra <= seq->start) nr= 0;
else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
@@ -1032,93 +912,12 @@ static int give_stripelem_index(Sequence *seq, int cfra)
}
if (seq->strobe < 1.0) seq->strobe = 1.0;
if (seq->strobe > 1.0) {
- nr -= (int)fmod((double)nr, (double)seq->strobe);
+ nr -= fmod((double)nr, (double)seq->strobe);
}
return nr;
}
-static TStripElem* alloc_tstripdata(int len, const char * name)
-{
- int i;
- TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
- for (i = 0; i < len; i++) {
- se[i].ok = STRIPELEM_OK;
- }
- return se;
-}
-
-static TStripElem *give_tstripelem(Sequence *seq, int cfra)
-{
- TStripElem *se;
- int nr;
-
- se = seq->strip->tstripdata;
- if (se == 0 && seq->len > 0) {
- se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
- "tstripelems");
- }
- nr = give_stripelem_index(seq, cfra);
-
- if (nr == -1) return 0;
- if (se == 0) return 0;
-
- se += nr;
-
- /* if there are IPOs with blend modes active, one has to watch out
- for startstill + endstill area: we can't use the same tstripelem
- here for all ibufs, since then, blending with IPOs won't work!
-
- Rather common case, if you use a single image and try to fade
- it in and out... or want to use your strip as a watermark in
- alpha over mode...
- */
- if (seq->blend_mode != SEQ_BLEND_REPLACE ||
- (/*seq->ipo && seq->ipo->curve.first &&*/
- (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
- Strip * s = seq->strip;
- if (cfra < seq->start) {
- se = s->tstripdata_startstill;
- if (seq->startstill > s->startstill) {
- free_tstripdata(s->startstill,
- s->tstripdata_startstill);
- se = 0;
- }
-
- if (se == 0) {
- s->startstill = seq->startstill;
- se = seq->strip->tstripdata_startstill
- = alloc_tstripdata(
- s->startstill,
- "tstripelems_startstill");
- }
- se += seq->start - cfra - 1;
-
- } else if (cfra > seq->start + seq->len-1) {
- se = s->tstripdata_endstill;
- if (seq->endstill > s->endstill) {
- free_tstripdata(s->endstill,
- s->tstripdata_endstill);
- se = 0;
- }
-
- if (se == 0) {
- s->endstill = seq->endstill;
- se = seq->strip->tstripdata_endstill
- = alloc_tstripdata(
- s->endstill,
- "tstripelems_endstill");
- }
- se += cfra - (seq->start + seq->len-1) - 1;
- }
- }
-
-
- se->nr= nr;
-
- return se;
-}
-
StripElem *give_stripelem(Sequence *seq, int cfra)
{
StripElem *se= seq->strip->stripdata;
@@ -1127,7 +926,7 @@ StripElem *give_stripelem(Sequence *seq, int cfra)
/* use the first */
}
else {
- int nr = give_stripelem_index(seq, cfra);
+ int nr = (int) give_stripelem_index(seq, cfra);
if (nr == -1) return 0;
if (se == 0) return 0;
@@ -1231,7 +1030,8 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
return FALSE;
}
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ if ((seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)
+ || (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE)) {
strcpy(dir, seq->strip->proxy->dir);
} else {
if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
@@ -1257,17 +1057,15 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
dir, render_size, se->name);
frameno = 1;
} else if (seq->type == SEQ_MOVIE) {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- frameno = tse->nr + seq->anim_startofs;
+ frameno = (int) give_stripelem_index(seq, cfra)
+ + seq->anim_startofs;
snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
seq->strip->stripdata->name,
render_size);
} else {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- frameno = tse->nr + seq->anim_startofs;
+ frameno = (int) give_stripelem_index(seq, cfra)
+ + seq->anim_startofs;
snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
render_size);
@@ -1296,10 +1094,11 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, in
}
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
- TStripElem * tse = give_tstripelem(seq, cfra);
- int frameno = tse->nr + seq->anim_startofs;
+ int frameno = (int) give_stripelem_index(seq, cfra)
+ + seq->anim_startofs;
if (!seq->strip->proxy->anim) {
- if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
+ if (!seq_proxy_get_fname(
+ scene, seq, cfra, name, render_size)) {
return 0;
}
@@ -1327,7 +1126,7 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, in
static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
int build_proxy_run, int render_size);
-static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
+static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
{
char name[PROXY_MAXFILE];
int quality;
@@ -1364,7 +1163,8 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
- do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
+ do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size,
+ seqrectx, seqrecty);
if (!se->ibuf) {
return;
@@ -1398,7 +1198,8 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
-static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
+static void seq_proxy_rebuild(Scene *scene, Sequence * seq, int seqrectx,
+ int seqrecty)
{
int cfra;
float rsize = seq->strip->proxy->size;
@@ -1430,7 +1231,8 @@ static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize);
+ seq_proxy_build_frame(scene, seq, cfra, rsize,
+ seqrectx, seqrecty);
tse->flag |= STRIPELEM_PREVIEW_DONE;
}
if (blender_test_break()) {
@@ -1444,7 +1246,8 @@ static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize);
+ seq_proxy_build_frame(scene, seq, cfra, rsize,
+ seqrectx, seqrecty);
tse->flag |= STRIPELEM_PREVIEW_DONE;
}
if (blender_test_break()) {
@@ -1466,15 +1269,21 @@ static StripColorBalance calc_cb(StripColorBalance * cb_)
StripColorBalance cb = *cb_;
int c;
- if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
- for (c = 0; c < 3; c++) {
- cb.lift[c] = 1.0 - cb.lift[c];
- }
- } else {
+ for (c = 0; c < 3; c++) {
+ cb.lift[c] = 2.0f - cb.lift[c];
+ }
+
+ if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
for (c = 0; c < 3; c++) {
- cb.lift[c] = -(1.0 - cb.lift[c]);
+ /* tweak to give more subtle results
+ * values above 1.0 are scaled */
+ if(cb.lift[c] > 1.0f)
+ cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0f) + 1.0f;
+
+ cb.lift[c] = 2.0f - cb.lift[c];
}
}
+
if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
for (c = 0; c < 3; c++) {
if (cb.gain[c] != 0.0) {
@@ -1498,25 +1307,27 @@ static StripColorBalance calc_cb(StripColorBalance * cb_)
return cb;
}
+/* note: lift is actually 2-lift */
+MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
+{
+ float x= (((in - 1.0f) * lift) + 1.0f) * gain;
+
+ /* prevent NaN */
+ if (x < 0.f) x = 0.f;
+
+ return powf(x, gamma) * mul;
+}
+
static void make_cb_table_byte(float lift, float gain, float gamma,
unsigned char * table, float mul)
{
int y;
for (y = 0; y < 256; y++) {
- float v = 1.0 * y / 255;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
- if ( v > 1.0) {
- v = 1.0;
- } else if (v < 0.0) {
- v = 0.0;
- }
+ float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
+ CLAMP(v, 0.0f, 1.0f);
table[y] = v * 255;
}
-
}
static void make_cb_table_float(float lift, float gain, float gamma,
@@ -1525,21 +1336,17 @@ static void make_cb_table_float(float lift, float gain, float gamma,
int y;
for (y = 0; y < 256; y++) {
- float v = (float) y * 1.0 / 255.0;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
+ float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
table[y] = v;
}
}
-static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
+static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul)
{
unsigned char cb_tab[3][256];
int c;
- unsigned char * p = (unsigned char*) se->ibuf->rect;
- unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
+ unsigned char * p = (unsigned char*) ibuf->rect;
+ unsigned char * e = p + ibuf->x * 4 * ibuf->y;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
@@ -1557,24 +1364,24 @@ static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
}
}
-static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
+static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul)
{
float cb_tab[4][256];
int c,i;
- unsigned char * p = (unsigned char*) se->ibuf->rect;
- unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
+ unsigned char * p = (unsigned char*) ibuf->rect;
+ unsigned char * e = p + ibuf->x * 4 * ibuf->y;
float * o;
StripColorBalance cb;
- imb_addrectfloatImBuf(se->ibuf);
+ imb_addrectfloatImBuf(ibuf);
- o = se->ibuf->rect_float;
+ o = ibuf->rect_float;
cb = calc_cb(seq->strip->color_balance);
for (c = 0; c < 3; c++) {
make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
- cb_tab[c], mul);
+ cb_tab[c], mul);
}
for (i = 0; i < 256; i++) {
@@ -1591,30 +1398,29 @@ static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
}
}
-static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
+static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul)
{
- float * p = se->ibuf->rect_float;
- float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
+ float * p = ibuf->rect_float;
+ float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
while (p < e) {
int c;
for (c = 0; c < 3; c++) {
- p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
- cb.gamma[c]) * mul;
+ p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
}
p += 4;
}
}
-static void color_balance(Sequence * seq, TStripElem* se, float mul)
+static void color_balance(Sequence * seq, ImBuf* ibuf, float mul)
{
- if (se->ibuf->rect_float) {
- color_balance_float_float(seq, se, mul);
+ if (ibuf->rect_float) {
+ color_balance_float_float(seq, ibuf, mul);
} else if(seq->flag & SEQ_MAKE_FLOAT) {
- color_balance_byte_float(seq, se, mul);
+ color_balance_byte_float(seq, ibuf, mul);
} else {
- color_balance_byte_byte(seq, se, mul);
+ color_balance_byte_byte(seq, ibuf, mul);
}
}
@@ -1637,44 +1443,49 @@ static void color_balance(Sequence * seq, TStripElem* se, float mul)
*/
-static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
+int input_have_to_preprocess(
+ Scene *scene, Sequence * seq, float cfra, int seqrectx, int seqrecty)
{
float mul;
if ((seq->flag & SEQ_FILTERY) ||
- (seq->flag & SEQ_USE_CROP) ||
- (seq->flag & SEQ_USE_TRANSFORM) ||
- (seq->flag & SEQ_FLIPX) ||
- (seq->flag & SEQ_FLIPY) ||
- (seq->flag & SEQ_USE_COLOR_BALANCE) ||
- (seq->flag & SEQ_MAKE_PREMUL) ||
- (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
+ (seq->flag & SEQ_USE_CROP) ||
+ (seq->flag & SEQ_USE_TRANSFORM) ||
+ (seq->flag & SEQ_FLIPX) ||
+ (seq->flag & SEQ_FLIPY) ||
+ (seq->flag & SEQ_USE_COLOR_BALANCE) ||
+ (seq->flag & SEQ_MAKE_PREMUL)) {
return TRUE;
}
mul = seq->mul;
- if(seq->blend_mode == SEQ_BLEND_REPLACE &&
- !(seq->type & SEQ_EFFECT)) {
+ if(seq->blend_mode == SEQ_BLEND_REPLACE) {
mul *= seq->blend_opacity / 100.0;
}
if (mul != 1.0) {
return TRUE;
}
+
+ if (seq->sat != 1.0) {
+ return TRUE;
+ }
return FALSE;
}
-static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
+static ImBuf * input_preprocess(
+ Scene *scene, Sequence *seq, float cfra, int seqrectx, int seqrecty,
+ ImBuf * ibuf)
{
float mul;
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
+ seq->strip->orx= ibuf->x;
+ seq->strip->ory= ibuf->y;
if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
- IMB_filtery(se->ibuf);
+ IMB_filtery(ibuf);
}
if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
@@ -1692,8 +1503,8 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
t = *seq->strip->transform;
}
- sx = se->ibuf->x - c.left - c.right;
- sy = se->ibuf->y - c.top - c.bottom;
+ sx = ibuf->x - c.left - c.right;
+ sy = ibuf->y - c.top - c.bottom;
dx = sx;
dy = sy;
@@ -1702,39 +1513,62 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
dy = scene->r.ysch;
}
- if (c.top + c.bottom >= se->ibuf->y ||
- c.left + c.right >= se->ibuf->x ||
+ if (c.top + c.bottom >= ibuf->y ||
+ c.left + c.right >= ibuf->x ||
t.xofs >= dx || t.yofs >= dy) {
- make_black_ibuf(se->ibuf);
+ make_black_ibuf(ibuf);
} else {
ImBuf * i;
- if (se->ibuf->rect_float) {
+ if (ibuf->rect_float) {
i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
} else {
i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
}
- IMB_rectcpy(i, se->ibuf,
- t.xofs, t.yofs,
- c.left, c.bottom,
- sx, sy);
-
- IMB_freeImBuf(se->ibuf);
+ IMB_rectcpy(i, ibuf,
+ t.xofs, t.yofs,
+ c.left, c.bottom,
+ sx, sy);
+
+ IMB_freeImBuf(ibuf);
- se->ibuf = i;
+ ibuf = i;
}
}
if(seq->flag & SEQ_FLIPX) {
- IMB_flipx(se->ibuf);
+ IMB_flipx(ibuf);
}
+
if(seq->flag & SEQ_FLIPY) {
- IMB_flipy(se->ibuf);
+ IMB_flipy(ibuf);
}
- if(seq->mul == 0.0) {
- seq->mul = 1.0;
+ if(seq->sat != 1.0f) {
+ /* inline for now, could become an imbuf function */
+ int i;
+ char *rct= (char *)ibuf->rect;
+ float *rctf= ibuf->rect_float;
+ const float sat= seq->sat;
+ float hsv[3];
+
+ if(rct) {
+ float rgb[3];
+ for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
+ rgb_byte_to_float(rct, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
+ rgb_float_to_byte(rgb, rct);
+ }
+ }
+
+ if(rctf) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
+ rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
+ }
+ }
}
mul = seq->mul;
@@ -1744,708 +1578,520 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
}
if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
- color_balance(seq, se, mul);
+ color_balance(seq, ibuf, mul);
mul = 1.0;
}
if(seq->flag & SEQ_MAKE_FLOAT) {
- if (!se->ibuf->rect_float) {
- int profile = IB_PROFILE_NONE;
-
- /* no color management:
- * don't disturb the existing profiles */
- SWAP(int, se->ibuf->profile, profile);
+ if (!ibuf->rect_float)
+ IMB_float_from_rect_simple(ibuf);
- IMB_float_from_rect(se->ibuf);
-
- SWAP(int, se->ibuf->profile, profile);
- }
- if (se->ibuf->rect) {
- imb_freerectImBuf(se->ibuf);
+ if (ibuf->rect) {
+ imb_freerectImBuf(ibuf);
}
}
if(mul != 1.0) {
- multibuf(se->ibuf, mul);
+ multibuf(ibuf, mul);
}
if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
- converttopremul(se->ibuf);
+ if(ibuf->depth == 32 && ibuf->zbuf == 0) {
+ IMB_premultiply_alpha(ibuf);
}
}
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
+ if(ibuf->x != seqrectx || ibuf->y != seqrecty ) {
if(scene->r.mode & R_OSA) {
- IMB_scaleImBuf(se->ibuf,
- (short)seqrectx, (short)seqrecty);
+ IMB_scaleImBuf(ibuf,
+ (short)seqrectx, (short)seqrecty);
} else {
- IMB_scalefastImBuf(se->ibuf,
+ IMB_scalefastImBuf(ibuf,
(short)seqrectx, (short)seqrecty);
}
}
+ return ibuf;
}
-/* test if image too small or discarded from cache: reload */
-
-static void test_and_auto_discard_ibuf(TStripElem * se)
+static ImBuf * copy_from_ibuf_still(Sequence * seq, float nr,
+ int seqrectx, int seqrecty)
{
- if (se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
- || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
+ ImBuf * rval = 0;
+ ImBuf * ibuf = 0;
- se->ibuf= 0;
- se->ok= STRIPELEM_OK;
- }
+ if (nr == 0) {
+ ibuf = seq_stripelem_cache_get(
+ seq, seqrectx, seqrecty, seq->start,
+ SEQ_STRIPELEM_IBUF_STARTSTILL);
+ }
+ if (nr == seq->len - 1) {
+ ibuf = seq_stripelem_cache_get(
+ seq, seqrectx, seqrecty, seq->start,
+ SEQ_STRIPELEM_IBUF_ENDSTILL);
}
- 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;
- }
+ if (ibuf) {
+ rval = IMB_dupImBuf(ibuf);
+ IMB_freeImBuf(ibuf);
}
+
+ return rval;
}
-static void test_and_auto_discard_ibuf_stills(Strip * strip)
+static void copy_to_ibuf_still(Sequence * seq, float nr,
+ ImBuf * ibuf)
{
- if (strip->ibuf_startstill) {
- if (!strip->ibuf_startstill->rect &&
- !strip->ibuf_startstill->rect_float) {
- IMB_freeImBuf(strip->ibuf_startstill);
- strip->ibuf_startstill = 0;
- }
+ if (nr == 0) {
+ seq_stripelem_cache_put(
+ seq, 0, 0, seq->start,
+ SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
}
- if (strip->ibuf_endstill) {
- if (!strip->ibuf_endstill->rect &&
- !strip->ibuf_endstill->rect_float) {
- IMB_freeImBuf(strip->ibuf_endstill);
- strip->ibuf_endstill = 0;
- }
+ if (nr == seq->len - 1) {
+ seq_stripelem_cache_put(
+ seq, 0, 0, seq->start,
+ SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
}
}
-static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
-{
- if (!se->ibuf) {
- if (se->nr == 0 && seq->strip->ibuf_startstill) {
- IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
-
- se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
- }
- if (se->nr == seq->len - 1
- && (seq->len != 1)
- && seq->strip->ibuf_endstill) {
- IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
-
- se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
- }
- }
-}
+/* **********************************************************************
+ strip rendering functions
+ ********************************************************************** */
-static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
-{
- if (se->ibuf) {
- if (se->nr == 0) {
- seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
+static ImBuf* seq_render_strip_stack(
+ Main *bmain, Scene *scene,
+ ListBase *seqbasep, float cfra, int chanshown, int render_size,
+ int seqrectx, int seqrecty);
- IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
- IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
- }
- if (se->nr == seq->len - 1 && seq->len != 1) {
- seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
+static ImBuf * seq_render_strip(Main *bmain, Scene *scene, Sequence * seq, float cfra,
+ int render_size,
+ int seqrectx, int seqrecty);
- IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
- IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
- }
- }
-}
-static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
+static ImBuf* seq_render_effect_strip_impl(
+ Main *bmain, Scene *scene, float cfra, Sequence *seq, int render_size,
+ int seqrectx, int seqrecty)
{
- Sequence* seq_arr[MAXSEQ+1];
+ float fac, facf;
+ int early_out;
int i;
- TStripElem* se = 0;
+ int must_preprocess = FALSE;
- evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
-
- for (i = 0; i < MAXSEQ; i++) {
- if (!video_seq_is_rendered(seq_arr[i])) {
- continue;
- }
- se = give_tstripelem(seq_arr[i], cfra);
- if (se) {
- if (se->ibuf) {
- IMB_freeImBuf(se->ibuf);
-
- se->ibuf= 0;
- se->ok= STRIPELEM_OK;
- }
+ struct SeqEffectHandle sh = get_sequence_effect(seq);
+ FCurve *fcu= NULL;
+ ImBuf * ibuf[3];
+ ImBuf * out = 0;
- if (se->ibuf_comp) {
- IMB_freeImBuf(se->ibuf_comp);
+ ibuf[0] = ibuf[1] = ibuf[2] = 0;
- se->ibuf_comp = 0;
- }
- }
+ if (!sh.execute) { /* effect not supported in this version... */
+ goto finish;
}
-
-}
-static void check_limiter_refcount(const char * func, TStripElem *se)
-{
- if (se && se->ibuf) {
- int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
- if (refcount != 1) {
- /* can happen on complex pipelines */
- if (refcount > 1 && (G.f & G_DEBUG) == 0) {
- return;
- }
-
- fprintf(stderr,
- "sequencer: (ibuf) %s: "
- "suspicious memcache "
- "limiter refcount: %d\n", func, refcount);
- }
- }
-}
-
-static void check_limiter_refcount_comp(const char * func, TStripElem *se)
-{
- if (se && se->ibuf_comp) {
- int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
- if (refcount != 1) {
- /* can happen on complex pipelines */
- if (refcount > 1 && (G.f & G_DEBUG) == 0) {
- return;
+ if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
+ sh.get_default_fac(seq, cfra, &fac, &facf);
+ if( scene->r.mode & R_FIELDS ); else facf= fac;
+ } else {
+ fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
+ "effect_fader", 0);
+ if (fcu) {
+ fac = facf = evaluate_fcurve(fcu, cfra);
+ if( scene->r.mode & R_FIELDS ) {
+ facf = evaluate_fcurve(fcu, cfra + 0.5);
}
- fprintf(stderr,
- "sequencer: (ibuf comp) %s: "
- "suspicious memcache "
- "limiter refcount: %d\n", func, refcount);
+ } else {
+ fac = facf = seq->effect_fader;
}
}
-}
-
-static TStripElem* do_build_seq_array_recursively(Scene *scene,
- ListBase *seqbasep, int cfra, int chanshown, int render_size);
-
-static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run, int render_size)
-{
- char name[FILE_MAXDIR+FILE_MAXFILE];
- int use_limiter = TRUE;
-
- test_and_auto_discard_ibuf(se);
- test_and_auto_discard_ibuf_stills(seq->strip);
-
- if(seq->type == SEQ_META) {
- TStripElem * meta_se = 0;
- int use_preprocess = FALSE;
- use_limiter = FALSE;
-
- if (!build_proxy_run && se->ibuf == 0) {
- se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- if (se->ibuf) {
- use_limiter = TRUE;
- use_preprocess = TRUE;
- }
- }
- if(!se->ibuf && seq->seqbase.first) {
- meta_se = do_build_seq_array_recursively(scene,
- &seq->seqbase, seq->start + se->nr, 0,
- render_size);
-
- check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
- }
-
- se->ok = STRIPELEM_OK;
-
- if(!se->ibuf && meta_se) {
- se->ibuf = meta_se->ibuf_comp;
- if(se->ibuf &&
- (!input_have_to_preprocess(scene, seq, se, cfra) ||
- build_proxy_run)) {
- IMB_refImBuf(se->ibuf);
- if (build_proxy_run) {
- IMB_cache_limiter_unref(se->ibuf);
- }
- } else if (se->ibuf) {
- struct ImBuf * i = IMB_dupImBuf(se->ibuf);
+ early_out = sh.early_out(seq, fac, facf);
- IMB_cache_limiter_unref(se->ibuf);
+ if (early_out == -1) { /* no input needed */
+ out = sh.execute(bmain, scene, seq, cfra, fac, facf,
+ seqrectx, seqrecty, render_size,
+ 0, 0, 0);
+ goto finish;
+ }
- se->ibuf = i;
- use_limiter = TRUE;
- use_preprocess = TRUE;
- }
- } else if (se->ibuf) {
- use_limiter = TRUE;
- }
- if (meta_se) {
- free_metastrip_imbufs(
- &seq->seqbase, seq->start + se->nr, 0);
- }
+ must_preprocess = input_have_to_preprocess(
+ scene, seq, cfra, seqrectx, seqrecty);
- if (use_preprocess) {
- input_preprocess(scene, seq, se, cfra);
- }
- } else if(seq->type & SEQ_EFFECT) {
- int use_preprocess = FALSE;
- /* should the effect be recalculated? */
-
- if (!build_proxy_run && se->ibuf == 0) {
- se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- if (se->ibuf) {
- use_preprocess = TRUE;
- }
+ switch (early_out) {
+ case 0:
+ break;
+ case 1:
+ if (seq->seq1) {
+ ibuf[0] = seq_render_strip(bmain, scene, seq->seq1, cfra,
+ render_size,
+ seqrectx, seqrecty);
}
-
- if(se->ibuf == 0) {
- /* if any inputs are rectfloat, output is float too */
- if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
- (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
- (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
-
- do_effect(scene, cfra, seq, se);
- if (input_have_to_preprocess(scene, seq, se, cfra) &&
- !build_proxy_run) {
- if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
- (se->se2 && (se->ibuf == se->se2->ibuf))) {
- struct ImBuf * i
- = IMB_dupImBuf(se->ibuf);
-
- IMB_freeImBuf(se->ibuf);
-
- se->ibuf = i;
- }
- use_preprocess = TRUE;
+ if (ibuf[0]) {
+ if (must_preprocess) {
+ out = IMB_dupImBuf(ibuf[0]);
+ } else {
+ out = ibuf[0];
+ IMB_refImBuf(out);
}
}
- if (use_preprocess) {
- input_preprocess(scene, seq, se, cfra);
- }
- } else if(seq->type == SEQ_IMAGE) {
- if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
- StripElem * s_elem = give_stripelem(seq, cfra);
- BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
- BLI_path_abs(name, G.sce);
- if (!build_proxy_run) {
- se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- }
- copy_from_ibuf_still(seq, se);
-
- if (!se->ibuf) {
- se->ibuf= IMB_loadiffname(
- name, IB_rect);
- /* we don't need both (speed reasons)! */
- if (se->ibuf &&
- se->ibuf->rect_float && se->ibuf->rect) {
- imb_freerectImBuf(se->ibuf);
- }
-
- copy_to_ibuf_still(seq, se);
- }
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else if (!build_proxy_run) {
- input_preprocess(scene, seq, se, cfra);
+ goto finish;
+ case 2:
+ if (seq->seq2) {
+ ibuf[1] = seq_render_strip(bmain, scene, seq->seq2, cfra,
+ render_size,
+ seqrectx, seqrecty);
+ }
+ if (ibuf[1]) {
+ if (must_preprocess) {
+ out = IMB_dupImBuf(ibuf[1]);
+ } else {
+ out = ibuf[1];
+ IMB_refImBuf(out);
}
}
- } else if(seq->type == SEQ_MOVIE) {
- if(se->ok == STRIPELEM_OK && se->ibuf==0) {
- if(!build_proxy_run) {
- se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- }
- copy_from_ibuf_still(seq, se);
+ goto finish;
+ default:
+ goto finish;
+ }
- if (se->ibuf == 0) {
- if(seq->anim==0) {
- BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
- BLI_path_abs(name, G.sce);
-
- seq->anim = openanim(
- name, IB_rect |
- ((seq->flag & SEQ_FILTERY)
- ? IB_animdeinterlace : 0));
- }
- if(seq->anim) {
- IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
- /* we don't need both (speed reasons)! */
- if (se->ibuf
- && se->ibuf->rect_float
- && se->ibuf->rect) {
- imb_freerectImBuf(se->ibuf);
- }
+ if (seq->seq1) {
+ ibuf[0] = seq_render_strip(bmain, scene, seq->seq1, cfra,
+ render_size,
+ seqrectx, seqrecty);
+ }
- }
- copy_to_ibuf_still(seq, se);
- }
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else if (!build_proxy_run) {
- input_preprocess(scene, seq, se, cfra);
- }
- }
- } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
- Scene *sce= seq->scene;// *oldsce= scene;
- int have_seq= FALSE;
- int sce_valid= FALSE;
+ if (seq->seq2) {
+ ibuf[1] = seq_render_strip(bmain, scene, seq->seq2, cfra,
+ render_size,
+ seqrectx, seqrecty);
+ }
- if(sce) {
- have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
- sce_valid= (sce->camera || have_seq);
- }
+ if (seq->seq3) {
+ ibuf[2] = seq_render_strip(bmain, scene, seq->seq3, cfra,
+ render_size,
+ seqrectx, seqrecty);
+ }
- if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
- se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- if (se->ibuf) {
- input_preprocess(scene, seq, se, cfra);
- }
- }
+ if (!ibuf[0] || !ibuf[1]) {
+ goto finish;
+ }
- if (se->ibuf == NULL && sce_valid) {
- copy_from_ibuf_still(seq, se);
- if (se->ibuf) {
- input_preprocess(scene, seq, se, cfra);
- }
- }
-
- if (!sce_valid) {
- se->ok = STRIPELEM_FAILED;
- }
- else if (se->ibuf==NULL && sce_valid) {
- int frame= seq->sfra + se->nr + seq->anim_startofs;
- int oldcfra = seq->scene->r.cfra;
- Object *oldcamera= seq->scene->camera;
- ListBase oldmarkers;
-
- /* Hack! This function can be called from do_render_seq(), in that case
- the seq->scene can already have a Render initialized with same name,
- so we have to use a default name. (compositor uses scene name to
- find render).
- However, when called from within the UI (image preview in sequencer)
- we do want to use scene Render, that way the render result is defined
- for display in render/imagewindow
-
- Hmm, don't see, why we can't do that all the time,
- and since G.rendering is uhm, gone... (Peter)
- */
-
- int rendering = 1;
- int doseq;
- int doseq_gl= G.rendering ? (scene->r.seq_flag & R_SEQ_GL_REND) : (scene->r.seq_flag & R_SEQ_GL_PREV);
-
- /* prevent eternal loop */
- doseq= scene->r.scemode & R_DOSEQ;
- scene->r.scemode &= ~R_DOSEQ;
-
- seq->scene->r.cfra= frame;
- if(seq->scene_camera) seq->scene->camera= seq->scene_camera;
- else scene_camera_switch_update(seq->scene);
+ out = sh.execute(bmain, scene, seq, cfra, fac, facf, seqrectx, seqrecty,
+ render_size,
+ ibuf[0], ibuf[1], ibuf[2]);
-#ifdef DURIAN_CAMERA_SWITCH
- /* stooping to new low's in hackyness :( */
- oldmarkers= seq->scene->markers;
- seq->scene->markers.first= seq->scene->markers.last= NULL;
-#endif
+finish:
+ for (i = 0; i < 3; i++) {
+ IMB_freeImBuf(ibuf[i]);
+ }
- if(sequencer_view3d_cb && doseq_gl && (seq->scene == scene || have_seq==0)) {
- /* opengl offscreen render */
- scene_update_for_newframe(seq->scene, seq->scene->lay);
- se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type);
- }
- else {
- Render *re;
- RenderResult rres;
+ if (!out) {
+ out = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
+ }
- if(rendering)
- re= RE_NewRender(" do_build_seq_ibuf");
- else
- re= RE_NewRender(sce->id.name);
+ return out;
+}
- RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
- RE_AcquireResultImage(re, &rres);
+static ImBuf * seq_render_scene_strip_impl(
+ Main *bmain, Scene * scene, Sequence * seq, float nr, int seqrectx, int seqrecty)
+{
+ ImBuf * ibuf = 0;
+ float frame= seq->sfra + nr + seq->anim_startofs;
+ float oldcfra;
+ Object *oldcamera;
+ ListBase oldmarkers;
+
+ /* Hack! This function can be called from do_render_seq(), in that case
+ the seq->scene can already have a Render initialized with same name,
+ so we have to use a default name. (compositor uses scene name to
+ find render).
+ However, when called from within the UI (image preview in sequencer)
+ we do want to use scene Render, that way the render result is defined
+ for display in render/imagewindow
+
+ Hmm, don't see, why we can't do that all the time,
+ and since G.rendering is uhm, gone... (Peter)
+ */
- if(rres.rectf) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
- memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
- if(rres.rectz) {
- addzbuffloatImBuf(se->ibuf);
- memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
- }
- } else if (rres.rect32) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
- memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
- }
+ int rendering = G.rendering;
+ int doseq;
+ int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV);
+ int have_seq= FALSE;
+ Scene *sce= seq->scene; /* dont refer to seq->scene above this point!, it can be NULL */
+ int sce_valid= FALSE;
- RE_ReleaseResultImage(re);
+ if(sce) {
+ have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
+ sce_valid= (sce->camera || have_seq);
+ }
- // BIF_end_render_callbacks();
- }
-
- /* restore */
- scene->r.scemode |= doseq;
+ if (!sce_valid)
+ return NULL;
- seq->scene->r.cfra = oldcfra;
- seq->scene->camera= oldcamera;
+ oldcfra= seq->scene->r.cfra;
+ oldcamera= seq->scene->camera;
+ /* prevent eternal loop */
+ doseq= scene->r.scemode & R_DOSEQ;
+ scene->r.scemode &= ~R_DOSEQ;
+
+ seq->scene->r.cfra= frame;
+ if(seq->scene_camera)
+ seq->scene->camera= seq->scene_camera;
+ else
+ scene_camera_switch_update(seq->scene);
+
#ifdef DURIAN_CAMERA_SWITCH
- /* stooping to new low's in hackyness :( */
- seq->scene->markers= oldmarkers;
+ /* stooping to new low's in hackyness :( */
+ oldmarkers= seq->scene->markers;
+ seq->scene->markers.first= seq->scene->markers.last= NULL;
#endif
-
- copy_to_ibuf_still(seq, se);
-
- if (!build_proxy_run) {
- if(se->ibuf == NULL) {
- se->ok = STRIPELEM_FAILED;
- } else {
- input_preprocess(scene, seq, se, cfra);
- }
+
+ if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) {
+ /* opengl offscreen render */
+ scene_update_for_newframe(bmain, seq->scene, seq->scene->lay);
+ ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, IB_rect,
+ scene->r.seq_prev_type);
+ }
+ else {
+ Render *re;
+ RenderResult rres;
+
+ if(rendering)
+ re= RE_NewRender(" do_build_seq_ibuf");
+ else
+ re= RE_NewRender(sce->id.name);
+
+ RE_BlenderFrame(re, bmain, sce, NULL, sce->lay, frame);
+
+ RE_AcquireResultImage(re, &rres);
+
+ if(rres.rectf) {
+ ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
+ memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
+ if(rres.rectz) {
+ addzbuffloatImBuf(ibuf);
+ memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
}
+ /* float buffers in the sequencer are not linear */
+ ibuf->profile= IB_PROFILE_LINEAR_RGB;
+ IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
}
- }
- if (!build_proxy_run) {
- if (se->ibuf && use_limiter) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
+ else if (rres.rect32) {
+ ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
+ memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
}
+
+ RE_ReleaseResultImage(re);
+
+ // BIF_end_render_callbacks();
}
-}
+
+ /* restore */
+ scene->r.scemode |= doseq;
+
+ seq->scene->r.cfra = oldcfra;
+ seq->scene->camera= oldcamera;
+
+#ifdef DURIAN_CAMERA_SWITCH
+ /* stooping to new low's in hackyness :( */
+ seq->scene->markers= oldmarkers;
+#endif
-static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
+ return ibuf;
+}
-static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
+static ImBuf * seq_render_strip(Main *bmain, Scene *scene, Sequence * seq, float cfra,
+ int render_size,
+ int seqrectx, int seqrecty)
{
- float fac, facf;
- struct SeqEffectHandle sh = get_sequence_effect(seq);
- int early_out;
- FCurve *fcu= NULL;
-
- se->se1 = 0;
- se->se2 = 0;
- se->se3 = 0;
-
- if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
- sh.get_default_fac(seq, cfra, &fac, &facf);
- if( scene->r.mode & R_FIELDS ); else facf= fac;
- } else {
- fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
- "effect_fader", 0);
- if (fcu) {
- fac = facf = evaluate_fcurve(fcu, cfra);
- if( scene->r.mode & R_FIELDS ) {
- facf = evaluate_fcurve(fcu, cfra + 0.5);
- }
- } else {
- fac = facf = seq->effect_fader;
- }
- }
+ char name[FILE_MAXDIR+FILE_MAXFILE];
+ int use_preprocess = input_have_to_preprocess(
+ scene, seq, cfra, seqrectx, seqrecty);
+ ImBuf * ibuf = seq_stripelem_cache_get(
+ seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF);
+ float nr = give_stripelem_index(seq, cfra);
- early_out = sh.early_out(seq, fac, facf);
- switch (early_out) {
- case -1:
- /* no input needed */
- break;
- case 0:
- se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
- se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
- if (seq->seq3) {
- se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
- }
- break;
- case 1:
- se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
- break;
- case 2:
- se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
- break;
+ /* currently, we cache preprocessed images */
+ if (ibuf) {
+ use_preprocess = FALSE;
}
+ if(seq->type == SEQ_META) {
+ ImBuf * meta_ibuf = 0;
- do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
+ if (ibuf == 0) {
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
+ }
- /* children are not needed anymore ... */
+ if(!ibuf && seq->seqbase.first) {
+ meta_ibuf = seq_render_strip_stack(
+ bmain, scene,
+ &seq->seqbase, seq->start + nr, 0,
+ render_size, seqrectx, seqrecty);
+ }
- if (se->se1 && se->se1->ibuf) {
- IMB_cache_limiter_unref(se->se1->ibuf);
- }
- if (se->se2 && se->se2->ibuf) {
- IMB_cache_limiter_unref(se->se2->ibuf);
- }
- if (se->se3 && se->se3->ibuf) {
- IMB_cache_limiter_unref(se->se3->ibuf);
- }
- check_limiter_refcount("do_effect_seq_recursively", se);
-}
+ if(!ibuf && meta_ibuf) {
+ ibuf = meta_ibuf;
+ if(ibuf && use_preprocess) {
+ struct ImBuf * i = IMB_dupImBuf(ibuf);
-static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
-{
- TStripElem *se;
+ IMB_freeImBuf(ibuf);
- se = give_tstripelem(seq, cfra);
+ ibuf = i;
+ }
+ }
+ } else if(seq->type == SEQ_SPEED) {
+ ImBuf * child_ibuf = 0;
- if(se) {
- if (seq->type & SEQ_EFFECT) {
- do_effect_seq_recursively(scene, seq, se, cfra, render_size);
- } else {
- do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
+ if (ibuf == 0) {
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
}
- }
- return se;
-}
-/* FIXME:
-
-If cfra was float throughout blender (especially in the render
-pipeline) one could even _render_ with subframe precision
-instead of faking using the blend code below...
+ if (ibuf == 0) {
+ float f_cfra;
+ SpeedControlVars * s
+ = (SpeedControlVars *)seq->effectdata;
-*/
+ sequence_effect_speed_rebuild_map(scene, seq, 0);
-static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
-{
- SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
- int nr = cfra - seq->start;
- float f_cfra;
- int cfra_left;
- int cfra_right;
- TStripElem * se = 0;
- TStripElem * se1 = 0;
- TStripElem * se2 = 0;
-
- sequence_effect_speed_rebuild_map(scene, seq, 0);
-
- f_cfra = seq->start + s->frameMap[nr];
-
- cfra_left = (int) floor(f_cfra);
- cfra_right = (int) ceil(f_cfra);
+ /* weeek! */
+ f_cfra = seq->start + s->frameMap[(int) nr];
- se = give_tstripelem(seq, cfra);
+ child_ibuf = seq_render_strip(bmain, scene, seq->seq1, f_cfra,
+ render_size,
+ seqrectx, seqrecty);
+ }
- if (!se) {
- return se;
- }
+ if (!ibuf && child_ibuf) {
+ ibuf = child_ibuf;
+ if(ibuf && use_preprocess) {
+ struct ImBuf * i = IMB_dupImBuf(ibuf);
- if (cfra_left == cfra_right ||
- (s->flags & SEQ_SPEED_BLEND) == 0) {
- test_and_auto_discard_ibuf(se);
+ IMB_freeImBuf(ibuf);
- if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
+ ibuf = i;
+ }
+ }
+ } else if(seq->type & SEQ_EFFECT) {
+ /* should the effect be recalculated? */
+
+ if (ibuf == 0) {
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
+ }
- if((se1 && se1->ibuf && se1->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
+ if(ibuf == 0) {
+ ibuf = seq_render_effect_strip_impl(
+ bmain, scene, cfra, seq, render_size,
+ seqrectx, seqrecty);
+ }
+ } else if(seq->type == SEQ_IMAGE) {
+ StripElem * s_elem = give_stripelem(seq, cfra);
- if (se1 == 0 || se1->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- } else {
- if (se->ibuf != se1->ibuf) {
- if (se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- }
+ if(ibuf == 0 && s_elem) {
+ BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
+ BLI_path_abs(name, G.sce);
- se->ibuf = se1->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- }
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
}
- } else {
- struct SeqEffectHandle sh;
- 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;
- }
+ if (ibuf == 0) {
+ ibuf = copy_from_ibuf_still(seq,nr,seqrectx,seqrecty);
}
- if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
- se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
+ if (ibuf == 0 && s_elem &&
+ (ibuf = IMB_loadiffname(name, IB_rect))) {
+ /* we don't need both (speed reasons)! */
+ if (ibuf->rect_float && ibuf->rect)
+ imb_freerectImBuf(ibuf);
+
+ /* all sequencer color is done in SRGB space, linear gives odd crossfades */
+ if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
+ IMB_convert_profile(ibuf, IB_PROFILE_NONE);
- if((se1 && se1->ibuf && se1->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
+ copy_to_ibuf_still(seq, nr, ibuf);
+ }
+ } else if(seq->type == SEQ_MOVIE) {
+ if(ibuf == 0) {
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
- if (!se1 || !se2) {
- make_black_ibuf(se->ibuf);
- } else {
- sh = get_sequence_effect(seq);
+ }
+
+ if (ibuf == 0) {
+ ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty);
+ }
+
+ if (ibuf == 0) {
+ if(seq->anim==0) {
+ BLI_join_dirfile(name,
+ seq->strip->dir,
+ seq->strip->stripdata->name);
+ BLI_path_abs(name, G.sce);
+
+ seq->anim = openanim(
+ name, IB_rect |
+ ((seq->flag & SEQ_FILTERY)
+ ? IB_animdeinterlace : 0));
+ }
+ if(seq->anim) {
+ IMB_anim_set_preseek(seq->anim,
+ seq->anim_preseek);
+ ibuf = IMB_anim_absolute(seq->anim,
+ nr
+ + seq->anim_startofs);
+ /* we don't need both (speed reasons)! */
+ if (ibuf && ibuf->rect_float
+ && ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ }
- sh.execute(scene, seq, cfra,
- f_cfra - (float) cfra_left,
- f_cfra - (float) cfra_left,
- se->ibuf->x, se->ibuf->y,
- se1->ibuf, se2->ibuf, 0, se->ibuf);
}
+ copy_to_ibuf_still(seq, nr, ibuf);
}
+
+ } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
+ if (ibuf == 0) {
+ ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
+ }
+ if (ibuf == 0) {
+ ibuf = copy_from_ibuf_still(seq, nr,seqrectx,seqrecty);
+ }
+
+ if (ibuf == 0) {
+ ibuf = seq_render_scene_strip_impl(bmain, scene, seq, nr,
+ seqrectx, seqrecty);
+ copy_to_ibuf_still(seq, nr, ibuf);
+ }
}
- /* caller expects this to be referenced, so do it! */
- if (se->ibuf) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
+ if (!ibuf) {
+ ibuf = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
}
- /* children are no longer needed */
- if (se1 && se1->ibuf)
- IMB_cache_limiter_unref(se1->ibuf);
- if (se2 && se2->ibuf)
- IMB_cache_limiter_unref(se2->ibuf);
-
- check_limiter_refcount("do_handle_speed_effect", se);
-
- return se;
-}
-
-/*
- * build all ibufs recursively
- *
- * if successfull, the returned TStripElem contains the (referenced!) imbuf
- * that means: you _must_ call
- *
- * IMB_cache_limiter_unref(rval);
- *
- * if rval != 0
- *
- */
+ if (ibuf->x != seqrectx || ibuf->y != seqrecty) {
+ use_preprocess = TRUE;
+ }
-static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
-{
- TStripElem *se;
- if (seq->type == SEQ_SPEED) {
- se = do_handle_speed_effect(scene, seq, cfra, render_size);
- } else {
- se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
+ if (use_preprocess) {
+ ibuf = input_preprocess(scene, seq, cfra, seqrectx,
+ seqrecty, ibuf);
}
- check_limiter_refcount("do_build_seq_recursively", se);
+ seq_stripelem_cache_put(
+ seq, seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF, ibuf);
- return se;
+ return ibuf;
}
+/* **********************************************************************
+ strip stack rendering functions
+ ********************************************************************** */
+
static int seq_must_swap_input_in_blend_mode(Sequence * seq)
{
int swap_input = FALSE;
@@ -2482,45 +2128,48 @@ static int seq_get_early_out_for_blend_mode(Sequence * seq)
return early_out;
}
-static TStripElem* do_build_seq_array_recursively(Scene *scene,
- ListBase *seqbasep, int cfra, int chanshown, int render_size)
+static ImBuf* seq_render_strip_stack(
+ Main *bmain, Scene *scene, ListBase *seqbasep, float cfra, int chanshown,
+ int render_size, int seqrectx, int seqrecty)
{
Sequence* seq_arr[MAXSEQ+1];
int count;
int i;
- TStripElem* se = 0;
+ ImBuf* out = 0;
count = get_shown_sequences(seqbasep, cfra, chanshown,
- (Sequence **)&seq_arr);
+ (Sequence **)&seq_arr);
if (!count) {
return 0;
}
- se = give_tstripelem(seq_arr[count - 1], cfra);
-
- if (!se) {
- return 0;
+#if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
+ if(scene->r.cfra != cfra) {
+ // XXX for prefetch and overlay offset!..., very bad!!!
+ AnimData *adt= BKE_animdata_from_id(&scene->id);
+ BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
}
+#endif
- test_and_auto_discard_ibuf(se);
+ out = seq_stripelem_cache_get(
+ seq_arr[count - 1],
+ seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP);
- 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 (out) {
+ return out;
}
-
if(count == 1) {
- se = do_build_seq_recursively(scene, seq_arr[0],
- cfra, render_size);
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
- }
- return se;
+ out = seq_render_strip(bmain, scene, seq_arr[0],
+ cfra, render_size,
+ seqrectx, seqrecty);
+ seq_stripelem_cache_put(
+ seq_arr[0],
+ seqrectx, seqrecty, cfra,
+ SEQ_STRIPELEM_IBUF_COMP, out);
+
+ return out;
}
@@ -2528,28 +2177,17 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
int early_out;
Sequence * seq = seq_arr[i];
- se = give_tstripelem(seq, cfra);
-
- test_and_auto_discard_ibuf(se);
+ out = seq_stripelem_cache_get(
+ seq,
+ seqrectx, seqrecty, cfra, SEQ_STRIPELEM_IBUF_COMP);
- if (se->ibuf_comp != 0) {
+ if (out) {
break;
}
if (seq->blend_mode == SEQ_BLEND_REPLACE) {
- do_build_seq_recursively(
- scene, seq, cfra, render_size);
-
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf);
- } else {
- 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);
- }
+ out = seq_render_strip(bmain, scene, seq, cfra,
+ render_size,
+ seqrectx, seqrecty);
break;
}
@@ -2558,152 +2196,87 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
switch (early_out) {
case -1:
case 2:
- do_build_seq_recursively(
- scene, seq, cfra, render_size);
-
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
- } else {
- 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);
- }
+ out = seq_render_strip(bmain, scene, seq, cfra,
+ render_size,
+ seqrectx, seqrecty);
break;
case 1:
if (i == 0) {
- se->ibuf_comp = IMB_allocImBuf(
+ out = 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(
- scene, seq, cfra, render_size);
-
- if (!se->ibuf) {
- se->ibuf = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
- }
if (i == 0) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
+ out = seq_render_strip(bmain, scene, seq, cfra,
+ render_size,
+ seqrectx, seqrecty);
}
+
break;
}
-
- if (se->ibuf_comp) {
+ if (out) {
break;
}
}
+ seq_stripelem_cache_put(
+ seq_arr[i], seqrectx, seqrecty, cfra,
+ SEQ_STRIPELEM_IBUF_COMP, out);
+
+
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);
-
- float facf = seq->blend_opacity / 100.0;
- int swap_input = seq_must_swap_input_in_blend_mode(seq);
- int early_out = seq_get_early_out_for_blend_mode(seq);
- switch (early_out) {
- case 0: {
- int x= se2->ibuf->x;
- int y= se2->ibuf->y;
+ if (seq_get_early_out_for_blend_mode(seq) == 0) {
+ struct SeqEffectHandle sh = get_sequence_blend(seq);
+ ImBuf * ibuf1 = out;
+ ImBuf * ibuf2 = seq_render_strip(bmain, scene, seq, cfra,
+ render_size,
+ seqrectx, seqrecty);
- if(se1->ibuf_comp == NULL)
- continue;
+ float facf = seq->blend_opacity / 100.0;
+ int swap_input
+ = seq_must_swap_input_in_blend_mode(seq);
- 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);
- }
+ int x= seqrectx;
+ int y= seqrecty;
-
- 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_comp);
- }
- if (!se2->ibuf->rect &&
- !se2->ibuf_comp->rect_float) {
- IMB_rect_from_float(se2->ibuf);
- }
-
if (swap_input) {
- sh.execute(scene, seq, cfra,
- facf, facf, x, y,
- se2->ibuf, se1->ibuf_comp, 0,
- se2->ibuf_comp);
+ out = sh.execute(bmain, scene, seq, cfra,
+ facf, facf, x, y, render_size,
+ ibuf2, ibuf1, 0);
} else {
- sh.execute(scene, seq, cfra,
- facf, facf, x, y,
- se1->ibuf_comp, se2->ibuf, 0,
- se2->ibuf_comp);
+ out = sh.execute(bmain, scene, seq, cfra,
+ facf, facf, x, y, render_size,
+ ibuf1, ibuf2, 0);
}
-
- 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;
+
+ IMB_freeImBuf(ibuf1);
+ IMB_freeImBuf(ibuf2);
}
- case 1: {
- se2->ibuf_comp = se1->ibuf_comp;
- if(se2->ibuf_comp)
- IMB_refImBuf(se2->ibuf_comp);
- break;
- }
- }
- se = se2;
+ seq_stripelem_cache_put(
+ seq_arr[i], seqrectx, seqrecty, cfra,
+ SEQ_STRIPELEM_IBUF_COMP, out);
}
- return se;
+ return out;
}
/*
* returned ImBuf is refed!
- * you have to unref after usage!
+ * you have to free after usage!
*/
-static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
+ImBuf *give_ibuf_seq(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
{
Editing *ed= seq_give_editing(scene, FALSE);
int count;
ListBase *seqbasep;
- TStripElem *se;
-
if(ed==NULL) return NULL;
@@ -2715,50 +2288,19 @@ static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, i
seqbasep= ed->seqbasep;
}
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
-
- if(!se) {
- return 0;
- }
-
- check_limiter_refcount_comp("give_ibuf_seq_impl", se);
-
- return se->ibuf_comp;
+ return seq_render_strip_stack(
+ bmain, scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
}
-ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
+ImBuf *give_ibuf_seqbase(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep)
{
- TStripElem* se;
-
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_recursively(scene, seq, cfra, render_size);
-
- if(!se) {
- return 0;
- }
-
- check_limiter_refcount("give_ibuf_seq_direct", se);
-
- if (se->ibuf) {
- IMB_cache_limiter_unref(se->ibuf);
- }
-
- return se->ibuf;
+ return seq_render_strip_stack(bmain, scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
}
-ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
-{
- ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
- if (i) {
- IMB_cache_limiter_unref(i);
- }
- return i;
+ImBuf *give_ibuf_seq_direct(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
+{
+ return seq_render_strip(bmain, scene, seq, cfra, render_size, rectx, recty);
}
#if 0
@@ -2789,7 +2331,7 @@ static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
-static volatile int seq_thread_shutdown = FALSE;
+static volatile int seq_thread_shutdown = TRUE;
static volatile int seq_last_given_monoton_cfra = 0;
static int monoton_cfra = 0;
@@ -3024,13 +2566,13 @@ static void seq_wait_for_prefetch_ready()
}
#endif
-ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
+ImBuf *give_ibuf_seq_threaded(Main *bmain, Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
{
PrefetchQueueElem *e = NULL;
int found_something = FALSE;
if (seq_thread_shutdown) {
- return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
+ return give_ibuf_seq(bmain, scene, rectx, recty, cfra, chanshown, render_size);
}
while (!e) {
@@ -3107,20 +2649,6 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int
/* Functions to free imbuf and anim data on changes */
-static void free_imbuf_strip_elem(TStripElem *se)
-{
- 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)
{
if(seq->anim) {
@@ -3129,63 +2657,10 @@ static void free_anim_seq(Sequence *seq)
}
}
-#if 0
-static void free_imbuf_seq_except(Scene *scene, int cfra)
-{
- Editing *ed= seq_give_editing(scene, FALSE);
- Sequence *seq;
- TStripElem *se;
- int a;
-
- if(ed==NULL) return;
-
- SEQ_BEGIN(ed, seq) {
- if(seq->strip) {
- TStripElem * curelem = give_tstripelem(seq, cfra);
-
- for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
- if(seq->type==SEQ_MOVIE)
- if(seq->startdisp > cfra || seq->enddisp < cfra)
- free_anim_seq(seq);
- free_proxy_seq(seq);
- }
- }
- SEQ_END
-}
-#endif
-
-void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
+void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage,
+ int keep_file_handles)
{
Sequence *seq;
- TStripElem *se;
- int a;
if (check_mem_usage) {
/* Let the cache limitor take care of this (schlaile) */
@@ -3211,39 +2686,19 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
}
}
+ seq_stripelem_cache_cleanup();
for(seq= seqbase->first; seq; seq= seq->next) {
if(seq->strip) {
- for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
- if(seq->type==SEQ_MOVIE)
+ if(seq->type==SEQ_MOVIE && !keep_file_handles)
free_anim_seq(seq);
if(seq->type==SEQ_SPEED) {
sequence_effect_speed_rebuild_map(scene, seq, 1);
}
}
if(seq->type==SEQ_META) {
- free_imbuf_seq(scene, &seq->seqbase, FALSE);
+ free_imbuf_seq(scene, &seq->seqbase, FALSE,
+ keep_file_handles);
}
if(seq->type==SEQ_SCENE) {
/* FIXME: recurs downwards,
@@ -3256,8 +2711,7 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
{
Sequence *subseq;
- int a, free_imbuf = 0;
- TStripElem *se;
+ int free_imbuf = 0;
/* recurs downwards to see if this seq depends on the changed seq */
@@ -3283,12 +2737,6 @@ static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *chan
if(free_imbuf) {
if(ibuf_change) {
- se= seq->strip->tstripdata;
- if (se) {
- for(a=0; a<seq->len; a++, se++)
- free_imbuf_strip_elem(se);
- }
-
if(seq->type == SEQ_MOVIE)
free_anim_seq(seq);
if(seq->type == SEQ_SPEED) {
@@ -3314,39 +2762,6 @@ void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_ch
update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
}
-#if 0 // XXX from 2.4x, needs updating
-void free_imbuf_seq()
-{
- Scene * sce = G.main->scene.first;
- while(sce) {
- free_imbuf_seq_editing(sce->ed);
- sce= sce->id.next;
- }
-}
-#endif
-
-#if 0 // XXX old animation system
-static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
-{
- /* force update of all sequences with this ipo, on ipo changes */
- Editing *ed= seq_give_editing(scene, FALSE);
- Sequence *seq;
-
- if(ed==NULL) return;
-
- SEQ_BEGIN(ed, seq) {
- if(seq->ipo == ipo) {
- update_changed_seq_and_deps(scene, seq, 0, 1);
- if(seq->type == SEQ_SPEED) {
- sequence_effect_speed_rebuild_map(seq, 1);
- }
- free_proxy_seq(seq);
- }
- }
- SEQ_END
-}
-#endif
-
/* seq funcs's for transforming internally
notice the difference between start/end and left/right.
@@ -3407,7 +2822,8 @@ void seq_tx_set_final_right(Sequence *seq, int val)
since they work a bit differently to normal image seq's (during transform) */
int seq_single_check(Sequence *seq)
{
- if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR))
+ if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR
+ || seq->type == SEQ_MULTICAM))
return 1;
else
return 0;
@@ -3730,6 +3146,57 @@ ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq)
return NULL;
}
+int seq_swap(Sequence *seq_a, Sequence *seq_b)
+{
+ char name[sizeof(seq_a->name)];
+
+ if(seq_a->len != seq_b->len)
+ return 0;
+
+ /* type checking, could be more advanced but disalow sound vs non-sound copy */
+ if(seq_a->type != seq_b->type) {
+ if(seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) {
+ return 0;
+ }
+
+ /* disallow effects to swap with non-effects strips */
+ if((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) {
+ return 0;
+ }
+
+ if((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) {
+ if(get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) {
+ return 0;
+ }
+ }
+ }
+
+ SWAP(Sequence, *seq_a, *seq_b);
+
+ /* swap back names so animation fcurves dont get swapped */
+ strcpy(name, seq_a->name+2);
+ strcpy(seq_a->name+2, seq_b->name+2);
+ strcpy(seq_b->name+2, name);
+
+ /* swap back opacity, and overlay mode */
+ SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
+ SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
+
+
+ SWAP(void *, seq_a->prev, seq_b->prev);
+ SWAP(void *, seq_a->next, seq_b->next);
+ SWAP(int, seq_a->start, seq_b->start);
+ SWAP(int, seq_a->startofs, seq_b->startofs);
+ SWAP(int, seq_a->endofs, seq_b->endofs);
+ SWAP(int, seq_a->startstill, seq_b->startstill);
+ SWAP(int, seq_a->endstill, seq_b->endstill);
+ SWAP(int, seq_a->machine, seq_b->machine);
+ SWAP(int, seq_a->startdisp, seq_b->startdisp);
+ SWAP(int, seq_a->enddisp, seq_b->enddisp);
+
+ return 1;
+}
+
/* XXX - hackish function needed for transforming strips! TODO - have some better solution */
void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
{
@@ -3754,6 +3221,62 @@ void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
}
}
+void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to)
+{
+ char str_from[32];
+ FCurve *fcu;
+ FCurve *fcu_last;
+ FCurve *fcu_cpy;
+ ListBase lb= {NULL, NULL};
+
+ if(scene->adt==NULL || scene->adt->action==NULL)
+ return;
+
+ sprintf(str_from, "[\"%s\"]", name_from);
+
+ fcu_last= scene->adt->action->curves.last;
+
+ for (fcu= scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu= fcu->next) {
+ if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str_from)) {
+ fcu_cpy= copy_fcurve(fcu);
+ BLI_addtail(&lb, fcu_cpy);
+ }
+ }
+
+ /* notice validate is 0, keep this because the seq may not be added to the scene yet */
+ BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_from, name_to, 0, 0, 0);
+
+ /* add the original fcurves back */
+ addlisttolist(&scene->adt->action->curves, &lb);
+}
+
+/* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
+static void seq_free_animdata(Scene *scene, Sequence *seq)
+{
+ char str[32];
+ FCurve *fcu;
+
+ if(scene->adt==NULL || scene->adt->action==NULL)
+ return;
+
+ sprintf(str, "[\"%s\"]", seq->name+2);
+
+ fcu= scene->adt->action->curves.first;
+
+ while (fcu) {
+ if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
+ FCurve *next_fcu = fcu->next;
+
+ BLI_remlink(&scene->adt->action->curves, fcu);
+ free_fcurve(fcu);
+
+ fcu = next_fcu;
+ } else {
+ fcu = fcu->next;
+ }
+ }
+}
+
Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
{
@@ -3772,14 +3295,14 @@ Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
}
-Sequence *active_seq_get(Scene *scene)
+Sequence *seq_active_get(Scene *scene)
{
Editing *ed= seq_give_editing(scene, FALSE);
if(ed==NULL) return NULL;
return ed->act_seq;
}
-void active_seq_set(Scene *scene, Sequence *seq)
+void seq_active_set(Scene *scene, Sequence *seq)
{
Editing *ed= seq_give_editing(scene, FALSE);
if(ed==NULL) return;
@@ -3787,12 +3310,41 @@ void active_seq_set(Scene *scene, Sequence *seq)
ed->act_seq= seq;
}
+int seq_active_pair_get(Scene *scene, Sequence **seq_act, Sequence **seq_other)
+{
+ Editing *ed= seq_give_editing(scene, FALSE);
+
+ *seq_act= seq_active_get(scene);
+
+ if(*seq_act == NULL) {
+ return 0;
+ }
+ else {
+ Sequence *seq;
+
+ *seq_other= NULL;
+
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ if(seq->flag & SELECT && (seq != (*seq_act))) {
+ if(*seq_other) {
+ return 0;
+ }
+ else {
+ *seq_other= seq;
+ }
+ }
+ }
+
+ return (*seq_other != NULL);
+ }
+}
+
/* api like funcs for adding */
void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
{
if(seq) {
- strcpy(seq->name, seq_load->name);
+ BLI_strncpy(seq->name+2, seq_load->name, sizeof(seq->name)-2);
seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
if(seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) {
@@ -3801,7 +3353,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
if(seq_load->flag & SEQ_LOAD_REPLACE_SEL) {
seq_load->flag |= SELECT;
- active_seq_set(scene, seq);
+ seq_active_set(scene, seq);
}
if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
@@ -3829,6 +3381,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
seq->flag= SELECT;
seq->start= cfra;
seq->machine= machine;
+ seq->sat= 1.0;
seq->mul= 1.0;
seq->blend_opacity = 100.0;
seq->volume = 1.0f;
@@ -3846,8 +3399,7 @@ Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
seq->type= SEQ_IMAGE;
- BLI_strncpy(seq->name+2, "Image", SEQ_NAME_MAXSTR-2);
- seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
+ seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
/* basic defaults */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
@@ -3855,8 +3407,8 @@ Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
strip->len = seq->len = seq_load->len ? seq_load->len : 1;
strip->us= 1;
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- BLI_split_dirfile(seq_load->path, strip->dir, se->name);
-
+ BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir));
+
seq_load_apply(scene, seq, seq_load);
return seq;
@@ -3874,7 +3426,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
AUD_SoundInfo info;
- sound = sound_new_file(CTX_data_main(C), seq_load->path);
+ sound = sound_new_file(CTX_data_main(C), seq_load->path); /* handles relative paths */
if (sound==NULL || sound->playback_handle == NULL) {
//if(op)
@@ -3922,6 +3474,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
{
Scene *scene= CTX_data_scene(C); /* only for sound */
+ char path[sizeof(seq_load->path)];
Sequence *seq, *soundseq; /* generic strip vars */
Strip *strip;
@@ -3929,14 +3482,18 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
struct anim *an;
- an = openanim(seq_load->path, IB_rect);
+ BLI_strncpy(path, seq_load->path, sizeof(path));
+ BLI_path_abs(path, G.sce);
+
+ an = openanim(path, IB_rect);
if(an==NULL)
return NULL;
seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
-
seq->type= SEQ_MOVIE;
+ seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
+
seq->anim= an;
seq->anim_preseek = IMB_anim_get_preseek(an);
BLI_strncpy(seq->name+2, "Movie", SEQ_NAME_MAXSTR-2);
@@ -3964,8 +3521,136 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
seq_load->channel--;
}
+ if(seq_load->name[0] == '\0')
+ BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
+
/* can be NULL */
seq_load_apply(scene, seq, seq_load);
return seq;
}
+
+
+static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag)
+{
+ Sequence *seqn = MEM_dupallocN(seq);
+
+ seq->tmp = seqn;
+ seqn->strip= MEM_dupallocN(seq->strip);
+
+ // XXX: add F-Curve duplication stuff?
+
+ if (seq->strip->crop) {
+ seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
+ }
+
+ if (seq->strip->transform) {
+ seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
+ }
+
+ if (seq->strip->proxy) {
+ seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
+ }
+
+ if (seq->strip->color_balance) {
+ seqn->strip->color_balance
+ = MEM_dupallocN(seq->strip->color_balance);
+ }
+
+ if(seq->type==SEQ_META) {
+ seqn->strip->stripdata = 0;
+
+ seqn->seqbase.first= seqn->seqbase.last= 0;
+ /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
+ /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
+ } else if(seq->type == SEQ_SCENE) {
+ seqn->strip->stripdata = 0;
+ if(seq->scene_sound)
+ seqn->scene_sound = sound_scene_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ } else if(seq->type == SEQ_MOVIE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ seqn->anim= 0;
+ } else if(seq->type == SEQ_SOUND) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ if(seq->scene_sound)
+ seqn->scene_sound = sound_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+
+ seqn->sound->id.us++;
+ } else if(seq->type == SEQ_IMAGE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ } else if(seq->type >= SEQ_EFFECT) {
+ if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
+ if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
+ if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
+
+ if (seq->type & SEQ_EFFECT) {
+ struct SeqEffectHandle sh;
+ sh = get_sequence_effect(seq);
+ if(sh.copy)
+ sh.copy(seq, seqn);
+ }
+
+ seqn->strip->stripdata = 0;
+
+ } else {
+ fprintf(stderr, "Aiiiiekkk! sequence type not "
+ "handled in duplicate!\nExpect a crash"
+ " now...\n");
+ }
+
+ if(dupe_flag & SEQ_DUPE_UNIQUE_NAME)
+ seqbase_unique_name_recursive(&scene->ed->seqbase, seqn);
+
+ if(dupe_flag & SEQ_DUPE_ANIM)
+ seq_dupe_animdata(scene, seq->name+2, seqn->name+2);
+
+ return seqn;
+}
+
+Sequence * seq_dupli_recursive(struct Scene *scene, Sequence * seq, int dupe_flag)
+{
+ Sequence * seqn = seq_dupli(scene, seq, dupe_flag);
+ if (seq->type == SEQ_META) {
+ Sequence *s;
+ for(s= seq->seqbase.first; s; s = s->next) {
+ Sequence *n = seq_dupli_recursive(scene, s, dupe_flag);
+ if (n) {
+ BLI_addtail(&seqn->seqbase, n);
+ }
+ }
+ }
+ return seqn;
+}
+
+void seqbase_dupli_recursive(Scene *scene, ListBase *nseqbase, ListBase *seqbase, int dupe_flag)
+{
+ Sequence *seq;
+ Sequence *seqn = 0;
+ Sequence *last_seq = seq_active_get(scene);
+
+ for(seq= seqbase->first; seq; seq= seq->next) {
+ seq->tmp= NULL;
+ if((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
+ seqn = seq_dupli(scene, seq, dupe_flag);
+ if (seqn) { /*should never fail */
+ if(dupe_flag & SEQ_DUPE_CONTEXT) {
+ seq->flag &= ~SEQ_ALLSEL;
+ seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
+ }
+
+ BLI_addtail(nseqbase, seqn);
+ if(seq->type==SEQ_META)
+ seqbase_dupli_recursive(scene, &seqn->seqbase, &seq->seqbase, dupe_flag);
+
+ if(dupe_flag & SEQ_DUPE_CONTEXT) {
+ if (seq == last_seq) {
+ seq_active_set(scene, seqn);
+ }
+ }
+ }
+ }
+ }
+}