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.c396
1 files changed, 247 insertions, 149 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 3aebbea789f..9ef30bdd49b 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -78,11 +78,6 @@
# include "AUD_C-API.h"
#endif
-#ifdef WIN32
-#define snprintf _snprintf
-#endif
-
-
static ImBuf* seq_render_strip_stack(
SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
@@ -218,6 +213,18 @@ void seq_free_sequence(Scene *scene, Sequence *seq)
MEM_freeN(seq);
}
+void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
+{
+ Sequence *iseq;
+
+ for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
+ seq_free_sequence_recurse(scene, iseq);
+ }
+
+ seq_free_sequence(scene, seq);
+}
+
+
Editing *seq_give_editing(Scene *scene, int alloc)
{
if (scene->ed == NULL && alloc) {
@@ -533,7 +540,7 @@ void calc_sequence_disp(Scene *scene, Sequence *seq)
seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
}
- seq_update_sound(scene, seq);
+ seq_update_sound_bounds(scene, seq);
}
static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
@@ -683,13 +690,16 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
}
case SEQ_MOVIE:
if(seq->anim) IMB_free_anim(seq->anim);
- seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
+ seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
if (!seq->anim) {
return;
}
- seq->len = IMB_anim_get_duration(seq->anim);
+ seq->len = IMB_anim_get_duration(seq->anim,
+ seq->strip->proxy ?
+ seq->strip->proxy->tc :
+ IMB_TC_RECORD_RUN);
seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
@@ -1117,7 +1127,7 @@ static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Se
return cnt;
}
-
+
/* **********************************************************************
proxy management
@@ -1125,49 +1135,106 @@ static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Se
#define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
+static IMB_Proxy_Size seq_rendersize_to_proxysize(int size)
+{
+ if (size >= 100) {
+ return IMB_PROXY_NONE;
+ }
+ if (size >= 99) {
+ return IMB_PROXY_100;
+ }
+ if (size >= 75) {
+ return IMB_PROXY_75;
+ }
+ if (size >= 50) {
+ return IMB_PROXY_50;
+ }
+ return IMB_PROXY_25;
+}
+
+static void seq_open_anim_file(Sequence * seq)
+{
+ char name[FILE_MAXDIR+FILE_MAXFILE];
+ StripProxy * proxy;
+
+ if(seq->anim != NULL) {
+ return;
+ }
+
+ BLI_join_dirfile(name, sizeof(name),
+ seq->strip->dir, seq->strip->stripdata->name);
+ BLI_path_abs(name, G.main->name);
+
+ seq->anim = openanim(name, IB_rect |
+ ((seq->flag & SEQ_FILTERY) ?
+ IB_animdeinterlace : 0), seq->streamindex);
+
+ if (seq->anim == NULL) {
+ return;
+ }
+
+ proxy = seq->strip->proxy;
+
+ if (proxy == NULL) {
+ return;
+ }
+
+ if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
+ }
+}
+
+
static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name)
{
int frameno;
- char dir[FILE_MAXDIR];
+ char dir[PROXY_MAXFILE];
+ int render_size = context.preview_render_size;
if (!seq->strip->proxy) {
return FALSE;
}
+ /* MOVIE tracks (only exception: custom files) are now handled
+ internally by ImBuf module for various reasons: proper time code
+ support, quicker index build, using one file instead
+ of a full directory of jpeg files, etc. Trying to support old
+ and new method at once could lead to funny effects, if people
+ have both, a directory full of jpeg files and proxy avis, so
+ sorry folks, please rebuild your proxies... */
+
if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) {
strcpy(dir, seq->strip->proxy->dir);
+ } else if (seq->type == SEQ_IMAGE) {
+ BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
} else {
- if (ELEM(seq->type, SEQ_IMAGE, SEQ_MOVIE)) {
- snprintf(dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir);
- } else {
- return FALSE;
- }
+ return FALSE;
}
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
- BLI_join_dirfile(name, FILE_MAX, dir, seq->strip->proxy->file); /* XXX, not real length */
+ BLI_join_dirfile(name, PROXY_MAXFILE,
+ dir, seq->strip->proxy->file);
BLI_path_abs(name, G.main->name);
return TRUE;
}
+ /* dirty hack to distinguish 100% render size from PROXY_100 */
+ if (render_size == 99) {
+ render_size = 100;
+ }
+
/* generate a separate proxy directory for each preview size */
- switch(seq->type) {
- case SEQ_IMAGE:
- snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
+ if (seq->type == SEQ_IMAGE) {
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
context.preview_render_size,
give_stripelem(seq, cfra)->name);
frameno = 1;
- break;
- case SEQ_MOVIE:
- frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
- snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
- seq->strip->stripdata->name, context.preview_render_size);
- break;
- default:
- frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
- snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
+ } else {
+ frameno = (int) give_stripelem_index(seq, cfra)
+ + seq->anim_startofs;
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
context.preview_render_size);
}
@@ -1182,13 +1249,18 @@ static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra,
static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int cfra)
{
char name[PROXY_MAXFILE];
+ IMB_Proxy_Size psize = seq_rendersize_to_proxysize(
+ context.preview_render_size);
+ int size_flags;
if (!(seq->flag & SEQ_USE_PROXY)) {
return NULL;
}
- /* rendering at 100% ? No real sense in proxy-ing, right? */
- if (context.preview_render_size == 100) {
+ size_flags = seq->strip->proxy->build_size_flags;
+
+ /* only use proxies, if they are enabled (even if present!) */
+ if (psize != IMB_PROXY_NONE && ((size_flags & psize) != psize)) {
return NULL;
}
@@ -1199,13 +1271,19 @@ static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int
return NULL;
}
- seq->strip->proxy->anim = openanim(name, IB_rect);
+ seq->strip->proxy->anim = openanim(name, IB_rect, 0);
}
if (seq->strip->proxy->anim==NULL) {
return NULL;
}
- return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
+ seq_open_anim_file(seq);
+
+ frameno = IMB_anim_index_get_frame_index(
+ seq->anim, seq->strip->proxy->tc, frameno);
+
+ return IMB_anim_absolute(seq->strip->proxy->anim, frameno,
+ IMB_TC_NONE, IMB_PROXY_NONE);
}
if (seq_proxy_get_fname(context, seq, cfra, name) == 0) {
@@ -1219,67 +1297,30 @@ static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int
}
}
-#if 0
-static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run, int preview_render_size);
-
-static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int preview_render_size, int seqrectx, int seqrecty)
+static void seq_proxy_build_frame(SeqRenderData context,
+ Sequence* seq, int cfra,
+ int proxy_render_size)
{
char name[PROXY_MAXFILE];
int quality;
- TStripElem * se;
- int ok;
int rectx, recty;
+ int ok;
struct ImBuf * ibuf;
- if (!(seq->flag & SEQ_USE_PROXY)) {
- return;
- }
-
- /* rendering at 100% ? No real sense in proxy-ing, right? */
- if (preview_render_size == 100) {
- return;
- }
-
- /* that's why it is called custom... */
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
+ if (!seq_proxy_get_fname(context, seq, cfra, name)) {
return;
}
- if (!seq_proxy_get_fname(scene, seq, cfra, name, preview_render_size)) {
- return;
- }
+ ibuf = seq_render_strip(context, seq, cfra);
- se = give_tstripelem(seq, cfra);
- if (!se) {
- return;
- }
-
- if(se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = 0;
- }
-
- do_build_seq_ibuf(scene, seq, se, cfra, TRUE, preview_render_size,
- seqrectx, seqrecty);
-
- if (!se->ibuf) {
- return;
- }
-
- rectx= (preview_render_size*scene->r.xsch)/100;
- recty= (preview_render_size*scene->r.ysch)/100;
-
- ibuf = se->ibuf;
+ rectx = (proxy_render_size * context.scene->r.xsch) / 100;
+ recty = (proxy_render_size * context.scene->r.ysch) / 100;
if (ibuf->x != rectx || ibuf->y != recty) {
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
}
- /* quality is fixed, otherwise one has to generate separate
- directories for every quality...
-
- depth = 32 is intentionally left in, otherwise ALPHA channels
+ /* depth = 32 is intentionally left in, otherwise ALPHA channels
won't work... */
quality = seq->strip->proxy->quality;
ibuf->ftype= JPG | quality;
@@ -1292,69 +1333,80 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int pr
}
IMB_freeImBuf(ibuf);
- se->ibuf = 0;
}
-static void seq_proxy_rebuild(Scene *scene, Sequence * seq, int seqrectx,
- int seqrecty)
+void seq_proxy_rebuild(struct Main * bmain, Scene *scene, Sequence * seq,
+ short *stop, short *do_update, float *progress)
{
+ SeqRenderData context;
int cfra;
- float rsize = seq->strip->proxy->size;
+ int tc_flags;
+ int size_flags;
+ int quality;
- waitcursor(1);
+ if (!seq->strip || !seq->strip->proxy) {
+ return;
+ }
- G.afbreek = 0;
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return;
+ }
- /* 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.
- */
+ tc_flags = seq->strip->proxy->build_tc_flags;
+ size_flags = seq->strip->proxy->build_size_flags;
+ quality = seq->strip->proxy->quality;
- for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
- TStripElem * tse = give_tstripelem(seq, cfra);
+ if (seq->type == SEQ_MOVIE) {
+ seq_open_anim_file(seq);
- tse->flag &= ~STRIPELEM_PREVIEW_DONE;
+ if (seq->anim) {
+ IMB_anim_index_rebuild(
+ seq->anim, tc_flags, size_flags, quality,
+ stop, do_update, progress);
+ }
+ return;
}
-
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return;
+ }
- /* 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)) {
-//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize,
- seqrectx, seqrecty);
- tse->flag |= STRIPELEM_PREVIEW_DONE;
- }
- if (blender_test_break()) {
- break;
- }
+ /* that's why it is called custom... */
+ if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
+ return;
+ }
+
+ /* fail safe code */
+
+ context = seq_new_render_data(
+ bmain, scene,
+ (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
+ (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f,
+ 100);
+
+ for (cfra = seq->startdisp + seq->startstill;
+ cfra < seq->enddisp - seq->endstill; cfra++) {
+ if (size_flags & IMB_PROXY_25) {
+ seq_proxy_build_frame(context, seq, cfra, 25);
}
- } 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)) {
-//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize,
- seqrectx, seqrecty);
- tse->flag |= STRIPELEM_PREVIEW_DONE;
- }
- if (blender_test_break()) {
- break;
- }
+ if (size_flags & IMB_PROXY_50) {
+ seq_proxy_build_frame(context, seq, cfra, 50);
+ }
+ if (size_flags & IMB_PROXY_75) {
+ seq_proxy_build_frame(context, seq, cfra, 75);
}
+ if (size_flags & IMB_PROXY_100) {
+ seq_proxy_build_frame(context, seq, cfra, 100);
+ }
+
+ *progress= (float)cfra/(seq->enddisp - seq->endstill
+ - seq->startdisp + seq->startstill);
+ *do_update= 1;
+
+ if(*stop || G.afbreek)
+ break;
}
- waitcursor(0);
}
-#endif
/* **********************************************************************
@@ -1571,6 +1623,8 @@ static ImBuf * input_preprocess(
{
float mul;
+ ibuf = IMB_makeSingleUser(ibuf);
+
if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
IMB_filtery(ibuf);
}
@@ -1775,7 +1829,7 @@ static ImBuf* seq_render_effect_strip_impl(
facf= fac;
}
else {
- fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0);
+ fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
if (fcu) {
fac = facf = evaluate_fcurve(fcu, cfra);
if( context.scene->r.mode & R_FIELDS ) {
@@ -2096,17 +2150,20 @@ static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfr
}
case SEQ_MOVIE:
{
- if(seq->anim==NULL) {
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
- BLI_path_abs(name, G.main->name);
-
- seq->anim = openanim(name, IB_rect |
- ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
- }
+ seq_open_anim_file(seq);
if(seq->anim) {
- IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs);
+ IMB_anim_set_preseek(seq->anim,
+ seq->anim_preseek);
+
+ ibuf = IMB_anim_absolute(
+ seq->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ?
+ seq->strip->proxy->tc
+ : IMB_TC_RECORD_RUN,
+ seq_rendersize_to_proxysize(
+ context.preview_render_size));
+
/* we don't need both (speed reasons)! */
if (ibuf && ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
@@ -2123,7 +2180,7 @@ static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfr
ibuf = seq_render_scene_strip_impl(context, seq, nr);
/* Scene strips update all animation, so we need to restore original state.*/
- BKE_animsys_evaluate_all_animation(context.bmain, cfra);
+ BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
@@ -2200,7 +2257,7 @@ static ImBuf* seq_render_strip_stack(
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);
+ BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
}
#endif
@@ -3145,16 +3202,33 @@ int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
return offset? 0:1;
}
-void seq_update_sound(Scene* scene, Sequence *seq)
+void seq_update_sound_bounds_all(Scene *scene)
{
- if(seq->scene_sound)
- {
+ Editing *ed = scene->ed;
+
+ if(ed) {
+ Sequence *seq;
+
+ for(seq = ed->seqbase.first; seq; seq = seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+ else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
+ seq_update_sound_bounds(scene, seq);
+ }
+ }
+ }
+}
+
+void seq_update_sound_bounds(Scene* scene, Sequence *seq)
+{
+ if(seq->scene_sound) {
sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
/* mute is set in seq_update_muting_recursive */
}
}
-static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequence *metaseq, int mute)
+static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
{
Sequence *seq;
int seqmute;
@@ -3170,26 +3244,49 @@ static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequen
if(seq == metaseq)
seqmute= 0;
- seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute);
+ seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
}
else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
if(seq->scene_sound) {
- sound_mute_scene_sound(scene, seq->scene_sound, seqmute);
+ sound_mute_scene_sound(seq->scene_sound, seqmute);
}
}
}
}
-void seq_update_muting(Scene *scene, Editing *ed)
+void seq_update_muting(Editing *ed)
{
if(ed) {
/* mute all sounds up to current metastack list */
MetaStack *ms= ed->metastack.last;
if(ms)
- seq_update_muting_recursive(scene, &ed->seqbase, ms->parseq, 1);
+ seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1);
else
- seq_update_muting_recursive(scene, &ed->seqbase, NULL, 0);
+ seq_update_muting_recursive(&ed->seqbase, NULL, 0);
+ }
+}
+
+static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
+{
+ Sequence *seq;
+
+ for(seq=seqbasep->first; seq; seq=seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_recursive(scene, &seq->seqbase, sound);
+ }
+ else if(seq->type == SEQ_SOUND) {
+ if(seq->scene_sound && sound == seq->sound) {
+ sound_update_scene_sound(seq->scene_sound, sound);
+ }
+ }
+ }
+}
+
+void seq_update_sound(struct Scene *scene, struct bSound *sound)
+{
+ if(scene->ed) {
+ seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
}
}
@@ -3446,7 +3543,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
if(seq->sound)
- sound_cache(seq->sound, 0);
+ sound_cache(seq->sound);
}
seq_load->tot_success++;
@@ -3473,6 +3570,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
seq->mul= 1.0;
seq->blend_opacity = 100.0;
seq->volume = 1.0f;
+ seq->pitch = 1.0f;
seq->scene_sound = NULL;
return seq;
@@ -3584,7 +3682,7 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
BLI_strncpy(path, seq_load->path, sizeof(path));
BLI_path_abs(path, G.main->name);
- an = openanim(path, IB_rect);
+ an = openanim(path, IB_rect, 0);
if(an==NULL)
return NULL;
@@ -3600,7 +3698,7 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
/* basic defaults */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
- strip->len = seq->len = IMB_anim_get_duration( an );
+ strip->len = seq->len = IMB_anim_get_duration( an, IMB_TC_RECORD_RUN );
strip->us= 1;
/* we only need 1 element for MOVIE strips */