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
path: root/source
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2008-02-03 21:58:46 +0300
committerPeter Schlaile <peter@schlaile.de>2008-02-03 21:58:46 +0300
commit7e7f5628c3c5b8105122c06426d9d870c17fb771 (patch)
tree3dc6866dba12587c4cf00cb6de822d5c44c824b8 /source
parentab662ae85c4c9d3a2e28f1c26926934708f57482 (diff)
== Sequencer ==
This adds low resolution proxy support to the blender sequencer, so that even HD editing should be possible on slower machines. The proxies are stored as directories of JPEG-files and are only activated, if you use preview-resolution rendering. For your final render, just switch back to full resolution and the original files are used again. It enables even proxying of whole effect pipelines and scene-strips (but you have to your own custom directory for file storage then, since blender has no filename, which could be taken as a sensible default directory reference)
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BSE_sequence.h1
-rw-r--r--source/blender/include/butspace.h1
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h10
-rw-r--r--source/blender/src/buttons_scene.c53
-rw-r--r--source/blender/src/sequence.c340
5 files changed, 339 insertions, 66 deletions
diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h
index 3f86c6b163b..9f15b729e1c 100644
--- a/source/blender/include/BSE_sequence.h
+++ b/source/blender/include/BSE_sequence.h
@@ -61,6 +61,7 @@ void free_editing(struct Editing *ed);
void calc_sequence(struct Sequence *seq);
void calc_sequence_disp(struct Sequence *seq);
void reload_sequence_new_file(struct Sequence * seq);
+void seq_proxy_rebuild(struct Sequence * seq);
void sort_seq(void);
void clear_scene_in_allseqs(struct Scene *sce);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index ebd1d696f2b..7d047610a3a 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -364,6 +364,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SEQ_BUT_RELOAD_ALL 1694
#define B_SEQ_BUT_TRANSFORM 1695
#define B_SEQ_BUT_RELOAD_FILE 1696
+#define B_SEQ_BUT_REBUILD_PROXY 1697
/* *********************** */
#define B_ARMATUREBUTS 1800
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 5e32476b4e0..8e8f84f0bb6 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -53,7 +53,7 @@ typedef struct TStripElem {
struct ImBuf *ibuf_comp;
struct TStripElem *se1, *se2, *se3;
short ok;
- short pad;
+ short flag;
int nr;
} TStripElem;
@@ -80,9 +80,6 @@ typedef struct StripColorBalance {
typedef struct StripProxy {
char dir[160];
- int format;
- int width;
- int height;
} StripProxy;
typedef struct Strip {
@@ -92,9 +89,9 @@ typedef struct Strip {
StripElem *stripdata;
char dir[160];
int orx, ory;
+ StripProxy *proxy;
StripCrop *crop;
StripTransform *transform;
- StripProxy *proxy;
StripColorBalance *color_balance;
TStripElem *tstripdata;
TStripElem *tstripdata_startstill;
@@ -259,6 +256,7 @@ typedef struct SpeedControlVars {
#define SEQ_USE_TRANSFORM 65536
#define SEQ_USE_CROP 131072
#define SEQ_USE_COLOR_BALANCE 262144
+#define SEQ_USE_PROXY_CUSTOM_DIR 524288
#define SEQ_COLOR_BALANCE_INVERSE_GAIN 1
#define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2
@@ -294,6 +292,8 @@ typedef struct SpeedControlVars {
#define STRIPELEM_OK 1
#define STRIPELEM_META 2
+#define STRIPELEM_PREVIEW_DONE 1
+
#define SEQ_BLEND_REPLACE 0
/* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical
to the table above. (Only those effects that handle _exactly_ two inputs,
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 6eb26e43274..4c85c11b147 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -1159,13 +1159,56 @@ static void seq_panel_proxy()
uiDefButBitI(block, TOG, SEQ_USE_PROXY,
B_SEQ_BUT_RELOAD, "Use Proxy",
- 10,140,150,19, &last_seq->flag,
+ 10,140,120,19, &last_seq->flag,
0.0, 21.0, 100, 0,
"Use a preview proxy for this strip");
-
+
if (last_seq->flag & SEQ_USE_PROXY) {
+ if (!last_seq->strip->proxy) {
+ last_seq->strip->proxy =
+ MEM_callocN(sizeof(struct StripProxy),
+ "StripProxy");
+ }
+
+ uiDefButBitI(block, TOG, SEQ_USE_PROXY_CUSTOM_DIR,
+ B_SEQ_BUT_RELOAD, "Custom Dir",
+ 130,140,120,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Use a custom directory to store data");
+ }
+
+ if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD, "Dir: ",
+ 10,120,240,19, last_seq->strip->proxy->dir,
+ 0.0, 160.0, 100, 0, "");
+ }
+ if (last_seq->flag & SEQ_USE_PROXY) {
+ if (G.scene->r.size == 100) {
+ uiDefBut(block, LABEL, 0,
+ "Full render size selected, ",
+ 10,100,240,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0,
+ "so no proxy enabled!",
+ 10,80,240,19, 0, 0, 0, 0, 0, "");
+ } else if (last_seq->type != SEQ_MOVIE
+ && last_seq->type != SEQ_IMAGE
+ && !(last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) {
+ uiDefBut(block, LABEL, 0,
+ "Cannot proxy this strip without ",
+ 10,100,240,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0,
+ "custom directory selection!",
+ 10,80,240,19, 0, 0, 0, 0, 0, "");
+ } else {
+ uiDefBut(block, BUT, B_SEQ_BUT_REBUILD_PROXY,
+ "Rebuild proxy",
+ 10,100,240,19, 0, 0, 0, 0, 0,
+ "Rebuild proxy for the "
+ "currently selected strip.");
+ }
}
uiBlockEndAlign(block);
@@ -1186,8 +1229,7 @@ void sequencer_panels()
panels = SEQ_PANEL_EDITING;
- if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE
- || type == SEQ_HD_SOUND) {
+ if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE) {
panels |= SEQ_PANEL_INPUT | SEQ_PANEL_FILTER | SEQ_PANEL_PROXY;
}
@@ -1237,6 +1279,9 @@ void do_sequencer_panels(unsigned short event)
case B_SEQ_BUT_RELOAD_FILE:
reload_sequence_new_file(last_seq);
break;
+ case B_SEQ_BUT_REBUILD_PROXY:
+ seq_proxy_rebuild(last_seq);
+ break;
case B_SEQ_BUT_RELOAD:
case B_SEQ_BUT_RELOAD_ALL:
update_seq_ipo_rect(last_seq);
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index 6ddb68ef644..8ff72005732 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -76,6 +76,10 @@
int seqrectx, seqrecty;
+/* **********************************************************************
+ alloc / free functions
+ ********************************************************************** */
+
void free_tstripdata(int len, TStripElem *se)
{
TStripElem *seo;
@@ -101,11 +105,6 @@ void free_tstripdata(int len, TStripElem *se)
}
-void seq_proxy_free(StripProxy * proxy)
-{
- MEM_freeN(proxy);
-}
-
void free_strip(Strip *strip)
{
strip->us--;
@@ -115,8 +114,10 @@ void free_strip(Strip *strip)
return;
}
- if(strip->stripdata) {
- MEM_freeN(strip->stripdata);
+ MEM_freeN(strip->stripdata);
+
+ if (strip->proxy) {
+ MEM_freeN(strip->proxy);
}
if (strip->crop) {
MEM_freeN(strip->crop);
@@ -124,9 +125,6 @@ void free_strip(Strip *strip)
if (strip->transform) {
MEM_freeN(strip->transform);
}
- if (strip->proxy) {
- seq_proxy_free(strip->proxy);
- }
if (strip->color_balance) {
MEM_freeN(strip->color_balance);
}
@@ -776,7 +774,7 @@ static int give_stripelem_index(Sequence *seq, int cfra)
if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
- if(seq->flag&SEQ_REVERSE_FRAMES) {
+ 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;
@@ -826,12 +824,11 @@ TStripElem *give_tstripelem(Sequence *seq, int cfra)
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...
-
- Performance TODO: seperate give_tstripelem for ibuf from
- give_tstripelem for ibuf_comp, so that caching works here again...
+ it in and out... or want to use your strip as a watermark in
+ alpha over mode...
*/
- if (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT)) {
+ if (seq->blend_mode != SEQ_BLEND_REPLACE ||
+ (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT))) {
Strip * s = seq->strip;
if (cfra < seq->start) {
se = s->tstripdata_startstill;
@@ -1013,6 +1010,211 @@ void set_meta_stripdata(Sequence *seqm)
}
}
+/* **********************************************************************
+ proxy management
+ ********************************************************************** */
+
+#define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
+
+static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
+{
+ int frameno;
+ char dir[FILE_MAXDIR];
+
+ if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ strcpy(dir, seq->strip->proxy->dir);
+ } else {
+ if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
+ snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
+ seq->strip->dir);
+ } else {
+ return FALSE;
+ }
+ }
+
+ /* generate a seperate proxy directory for each preview size */
+
+ if (seq->type == SEQ_IMAGE) {
+ StripElem * se = give_stripelem(seq, cfra);
+ snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
+ dir, G.scene->r.size, se->name);
+ frameno = 1;
+ } else if (seq->type == SEQ_MOVIE) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ frameno = tse->nr + seq->anim_startofs;
+
+ snprintf(name, PROXY_MAXFILE, "%s/%s/%d/#", dir,
+ seq->strip->stripdata->name,
+ G.scene->r.size);
+ } else {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ frameno = tse->nr + seq->anim_startofs;
+
+ snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/#", dir,
+ G.scene->r.size);
+ }
+
+ if (seq->strip->proxy == 0) {
+ return FALSE;
+ }
+
+
+ BLI_convertstringcode(name, G.sce, frameno);
+
+ strcat(name, ".jpg");
+
+ return TRUE;
+}
+
+static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra)
+{
+ char name[PROXY_MAXFILE];
+
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return 0;
+ }
+
+ /* rendering at 100% ? No real sense in proxy-ing, right? */
+ if (G.scene->r.size == 100.0) {
+ return 0;
+ }
+
+ if (!seq_proxy_get_fname(seq, cfra, name)) {
+ return 0;
+ }
+
+ if (BLI_exists(name)) {
+ return IMB_loadiffname(name, IB_rect);
+ } else {
+ return 0;
+ }
+}
+
+static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
+ int build_proxy_run);
+
+static void seq_proxy_build_frame(Sequence * seq, int cfra)
+{
+ char name[PROXY_MAXFILE];
+ int quality;
+ TStripElem * se;
+ int ok;
+ int rectx, recty;
+ struct ImBuf * ibuf;
+
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return;
+ }
+
+ /* rendering at 100% ? No real sense in proxy-ing, right? */
+ if (G.scene->r.size == 100.0) {
+ return;
+ }
+
+ if (!seq_proxy_get_fname(seq, cfra, name)) {
+ return;
+ }
+
+ se = give_tstripelem(seq, cfra);
+
+ if(se->ibuf) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf = 0;
+ }
+
+ do_build_seq_ibuf(seq, se, cfra, TRUE);
+
+ if (!se->ibuf) {
+ return;
+ }
+
+ rectx= (G.scene->r.size*G.scene->r.xsch)/100;
+ recty= (G.scene->r.size*G.scene->r.ysch)/100;
+
+ ibuf = se->ibuf;
+
+ if (ibuf->x != rectx || ibuf->y != recty) {
+ IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
+ }
+
+ /* quality is fixed, otherwise one has to generate seperate
+ directories for every quality...
+
+ depth = 32 is intentionally left in, otherwise ALPHA channels
+ won't work... */
+ quality = 90;
+ ibuf->ftype= JPG | quality;
+
+ BLI_make_existing_file(name);
+
+ ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
+ if (ok == 0) {
+ perror(name);
+ }
+
+ IMB_freeImBuf(ibuf);
+ se->ibuf = 0;
+}
+
+void seq_proxy_rebuild(Sequence * seq)
+{
+ int cfra;
+
+ waitcursor(1);
+
+ G.afbreek = 0;
+
+ /* flag management tries to account for strobe and
+ other "non-linearities", that might come in the future...
+ better way would be to "touch" the files, so that _really_
+ no one is rebuild twice.
+ */
+
+ for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ tse->flag &= ~STRIPELEM_PREVIEW_DONE;
+ }
+
+ /* a _lot_ faster for movie files, if we read frames in
+ sequential order */
+ if (seq->flag & SEQ_REVERSE_FRAMES) {
+ for (cfra = seq->enddisp-seq->endstill-1;
+ cfra >= seq->startdisp + seq->startstill; cfra--) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
+ seq_proxy_build_frame(seq, cfra);
+ tse->flag |= STRIPELEM_PREVIEW_DONE;
+ }
+ if (blender_test_break()) {
+ break;
+ }
+ }
+ } else {
+ for (cfra = seq->startdisp + seq->startstill;
+ cfra < seq->enddisp - seq->endstill; cfra++) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
+ seq_proxy_build_frame(seq, cfra);
+ tse->flag |= STRIPELEM_PREVIEW_DONE;
+ }
+ if (blender_test_break()) {
+ break;
+ }
+ }
+ }
+ waitcursor(0);
+}
+
+
+/* **********************************************************************
+ color balance
+ ********************************************************************** */
+
static StripColorBalance calc_cb(StripColorBalance * cb_)
{
StripColorBalance cb = *cb_;
@@ -1333,7 +1535,8 @@ static void test_and_auto_discard_ibuf(TStripElem * se)
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)
+static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
+ int build_proxy_run)
{
char name[FILE_MAXDIR+FILE_MAXFILE];
@@ -1373,6 +1576,10 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra)
} else if(seq->type & SEQ_EFFECT) {
/* should the effect be recalculated? */
+ if (!build_proxy_run && se->ibuf == 0) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ }
+
if(se->ibuf == 0) {
/* if one of two first inputs are rectfloat, output is float too */
if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
@@ -1383,53 +1590,67 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra)
do_effect(cfra, seq, se);
}
-
- } else if(seq->type < SEQ_EFFECT) {
-
- if(seq->type==SEQ_IMAGE) {
- if(se->ok == STRIPELEM_OK && se->ibuf==0) {
- StripElem * s_elem = give_stripelem(seq, cfra);
-
- strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
- strncat(name, s_elem->name, FILE_MAXFILE);
- BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
- se->ibuf= IMB_loadiffname(name, IB_rect);
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else {
- input_preprocess(seq, se, cfra);
- }
+ } else if(seq->type == SEQ_IMAGE) {
+ if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
+ StripElem * s_elem = give_stripelem(seq, cfra);
+
+ strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
+ strncat(name, s_elem->name, FILE_MAXFILE);
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+ if (!build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ }
+ if (!se->ibuf) {
+ se->ibuf= IMB_loadiffname(
+ name, IB_rect);
+ }
+
+ if(se->ibuf == 0) {
+ se->ok = STRIPELEM_FAILED;
+ } else if (!build_proxy_run) {
+ input_preprocess(seq, se, cfra);
}
}
- else if(seq->type==SEQ_MOVIE) {
- if(se->ok == STRIPELEM_OK && se->ibuf==0) {
+ } else if(seq->type == SEQ_MOVIE) {
+ if(se->ok == STRIPELEM_OK && se->ibuf==0) {
+ if(!build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ }
+
+ if (se->ibuf == 0) {
if(seq->anim==0) {
strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
-
+
seq->anim = openanim(name, IB_rect);
}
if(seq->anim) {
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
}
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else {
- input_preprocess(seq, se, cfra);
- }
}
- } else if(seq->type==SEQ_SCENE && se->ibuf==NULL && seq->scene) { // scene can be NULL after deletions
- int oldcfra = CFRA;
- Scene *sce= seq->scene, *oldsce= G.scene;
- Render *re;
- RenderResult rres;
- int doseq, rendering= G.rendering;
- char scenename[64];
+ if(se->ibuf == 0) {
+ se->ok = STRIPELEM_FAILED;
+ } else if (!build_proxy_run) {
+ input_preprocess(seq, se, cfra);
+ }
+ }
+ } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
+ int oldcfra = CFRA;
+ Scene *sce= seq->scene, *oldsce= G.scene;
+ Render *re;
+ RenderResult rres;
+ int doseq, rendering= G.rendering;
+ char scenename[64];
+
+ if (se->ibuf==NULL && seq->scene && !build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ input_preprocess(seq, se, cfra);
+ }
+
+ if (se->ibuf==NULL && seq->scene) {
waitcursor(1);
/* Hack! This function can be called from do_render_seq(), in that case
@@ -1485,13 +1706,18 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra)
waitcursor(0);
CFRA = oldcfra;
- input_preprocess(seq, se, cfra);
+ if (!build_proxy_run) {
+ input_preprocess(seq, se, cfra);
+ }
+
}
}
- if (se->ibuf && seq->type != SEQ_META) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
+ if (!build_proxy_run) {
+ if (se->ibuf && seq->type != SEQ_META) {
+ IMB_cache_limiter_insert(se->ibuf);
+ IMB_cache_limiter_ref(se->ibuf);
+ IMB_cache_limiter_touch(se->ibuf);
+ }
}
}
@@ -1538,7 +1764,7 @@ static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
}
- do_build_seq_ibuf(seq, se, cfra);
+ do_build_seq_ibuf(seq, se, cfra, FALSE);
/* children are not needed anymore ... */
@@ -1563,7 +1789,7 @@ static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
if (seq->type & SEQ_EFFECT) {
do_effect_seq_recursively(seq, se, cfra);
} else {
- do_build_seq_ibuf(seq, se, cfra);
+ do_build_seq_ibuf(seq, se, cfra, FALSE);
}
}
return se;