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.c1425
1 files changed, 1103 insertions, 322 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index c9647b05ce7..f0e59eda321 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -53,7 +53,13 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#else
+# include <unistd.h>
+#endif
+
+#include "BLT_translation.h"
#include "BKE_animsys.h"
#include "BKE_depsgraph.h"
@@ -66,6 +72,7 @@
#include "BKE_scene.h"
#include "BKE_mask.h"
#include "BKE_library.h"
+#include "BKE_idprop.h"
#include "RNA_access.h"
@@ -81,13 +88,15 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include "AUD_C-API.h"
+# include AUD_SPECIAL_H
#endif
static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown);
static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, float cfra);
static void seq_free_animdata(Scene *scene, Sequence *seq);
static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float);
+static size_t seq_num_files(Scene *scene, char views_format, const bool is_multiview);
+static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const size_t view_id);
/* **** XXX ******** */
#define SELECT 1
@@ -180,10 +189,7 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach
if (seq->strip)
seq_free_strip(seq->strip);
- if (seq->anim) {
- IMB_free_anim(seq->anim);
- seq->anim = NULL;
- }
+ BKE_sequence_free_anim(seq);
if (seq->type & SEQ_TYPE_EFFECT) {
struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
@@ -195,6 +201,10 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach
((ID *)seq->sound)->us--;
}
+ if (seq->stereo3d_format) {
+ MEM_freeN(seq->stereo3d_format);
+ }
+
/* clipboard has no scene and will never have a sound handle or be active
* same goes to sequences copy for proxy rebuild job
*/
@@ -205,11 +215,16 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach
ed->act_seq = NULL;
if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE))
- sound_remove_scene_sound(scene, seq->scene_sound);
+ BKE_sound_remove_scene_sound(scene, seq->scene_sound);
seq_free_animdata(scene, seq);
}
+ if (seq->prop) {
+ IDP_FreeProperty(seq->prop);
+ MEM_freeN(seq->prop);
+ }
+
/* free modifiers */
BKE_sequence_modifier_clear(seq);
@@ -234,6 +249,22 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
BKE_sequence_free_ex(scene, seq, true);
}
+/* Function to free imbuf and anim data on changes */
+void BKE_sequence_free_anim(Sequence *seq)
+{
+ while (seq->anims.last) {
+ StripAnim *sanim = seq->anims.last;
+
+ if (sanim->anim) {
+ IMB_free_anim(sanim->anim);
+ sanim->anim = NULL;
+ }
+
+ BLI_freelinkN(&seq->anims, sanim);
+ }
+ BLI_listbase_clear(&seq->anims);
+}
+
/* cache must be freed before calling this function
* since it leaves the seqbase in an invalid state */
static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
@@ -257,26 +288,15 @@ Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
return scene->ed;
}
-static void seq_free_clipboard_recursive(Sequence *seq_parent)
-{
- Sequence *seq, *nseq;
-
- for (seq = seq_parent->seqbase.first; seq; seq = nseq) {
- nseq = seq->next;
- seq_free_clipboard_recursive(seq);
- }
-
- BKE_sequence_clipboard_pointers_free(seq_parent);
- BKE_sequence_free_ex(NULL, seq_parent, false);
-}
-
void BKE_sequencer_free_clipboard(void)
{
Sequence *seq, *nseq;
+ BKE_sequencer_base_clipboard_pointers_free(&seqbase_clipboard);
+
for (seq = seqbase_clipboard.first; seq; seq = nseq) {
nseq = seq->next;
- seq_free_clipboard_recursive(seq);
+ seq_free_sequence_recurse(NULL, seq);
}
BLI_listbase_clear(&seqbase_clipboard);
}
@@ -327,7 +347,7 @@ static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
{
id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->name, offsetof(bSound, name));
if (id_restore == NULL) {
- id_restore = sound_new_file(bmain, ((bSound *)ID_PT)->name);
+ id_restore = BKE_sound_new_file(bmain, ((bSound *)ID_PT)->name);
(ID_PT)->newid = id_restore; /* reuse next time */
}
break;
@@ -373,6 +393,33 @@ void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain)
seqclipboard_ptr_restore(bmain, (ID **)&seq->mask);
seqclipboard_ptr_restore(bmain, (ID **)&seq->sound);
}
+
+/* recursive versions of funcions above */
+void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_free(seq);
+ BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase);
+ }
+}
+void BKE_sequencer_base_clipboard_pointers_store(ListBase *seqbase)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_store(seq);
+ BKE_sequencer_base_clipboard_pointers_store(&seq->seqbase);
+ }
+}
+void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_restore(seq, bmain);
+ BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain);
+ }
+}
+
/* end clipboard pointer mess */
@@ -499,24 +546,23 @@ void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixe
/*********************** sequencer pipeline functions *************************/
-SeqRenderData BKE_sequencer_new_render_data(EvaluationContext *eval_ctx,
- Main *bmain, Scene *scene, int rectx, int recty,
- int preview_render_size)
-{
- SeqRenderData rval;
-
- rval.bmain = bmain;
- rval.scene = scene;
- rval.rectx = rectx;
- rval.recty = recty;
- rval.preview_render_size = preview_render_size;
- rval.motion_blur_samples = 0;
- rval.motion_blur_shutter = 0;
- rval.eval_ctx = eval_ctx;
- rval.skip_cache = false;
- rval.is_proxy_render = false;
-
- return rval;
+void BKE_sequencer_new_render_data(
+ EvaluationContext *eval_ctx,
+ Main *bmain, Scene *scene, int rectx, int recty,
+ int preview_render_size,
+ SeqRenderData *r_context)
+{
+ r_context->eval_ctx = eval_ctx;
+ r_context->bmain = bmain;
+ r_context->scene = scene;
+ r_context->rectx = rectx;
+ r_context->recty = recty;
+ r_context->preview_render_size = preview_render_size;
+ r_context->motion_blur_samples = 0;
+ r_context->motion_blur_shutter = 0;
+ r_context->skip_cache = false;
+ r_context->is_proxy_render = false;
+ r_context->view_id = 0;
}
/* ************************* iterator ************************** */
@@ -638,7 +684,7 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase
if (seq->start + seq->len - seq->endofs > end)
endofs = seq->start + seq->len - end;
- sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs,
+ BKE_sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs,
seq->start + seq->len - endofs, startofs + seq->anim_startofs);
}
}
@@ -751,10 +797,17 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
}
}
+static void seq_multiview_name(Scene *scene, const size_t view_id, const char *prefix,
+ const char *ext, char *r_path, size_t r_size)
+{
+ const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id);
+ BLI_snprintf(r_path, r_size, "%s%s%s", prefix, suffix, ext);
+}
+
/* note: caller should run BKE_sequence_calc(scene, seq) after */
void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, const bool lock_range)
{
- char str[FILE_MAX];
+ char path[FILE_MAX];
int prev_startdisp = 0, prev_enddisp = 0;
/* note: don't rename the strip, will break animation curves */
@@ -787,22 +840,67 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, const bool lock_r
break;
}
case SEQ_TYPE_MOVIE:
- BLI_join_dirfile(str, sizeof(str), seq->strip->dir,
+ {
+ StripAnim *sanim;
+ bool is_multiview_loaded = false;
+ const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
+ (scene->r.scemode & R_MULTIVIEW) != 0;
+
+ BLI_join_dirfile(path, sizeof(path), seq->strip->dir,
seq->strip->stripdata->name);
- BLI_path_abs(str, G.main->name);
+ BLI_path_abs(path, G.main->name);
+
+ BKE_sequence_free_anim(seq);
+
+ if (is_multiview && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
+ char prefix[FILE_MAX];
+ const char *ext = NULL;
+ size_t totfiles = seq_num_files(scene, seq->views_format, true);
+ int i = 0;
+
+ BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
+
+ if (prefix[0] != '\0') {
+ for (i = 0; i < totfiles; i++) {
+ struct anim *anim;
+ char str[FILE_MAX];
- if (seq->anim) IMB_free_anim(seq->anim);
+ seq_multiview_name(scene, i, prefix, ext, str, FILE_MAX);
+ anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+
+ if (anim) {
+ seq_anim_add_suffix(scene, anim, i);
+ sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
+ sanim->anim = anim;
+ }
+ }
+ is_multiview_loaded = true;
+ }
+ }
+
+ if (is_multiview_loaded == false) {
+ struct anim *anim;
+ anim = openanim(path, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ if (anim) {
+ sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
+ sanim->anim = anim;
+ }
+ }
- seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
- seq->streamindex, seq->strip->colorspace_settings.name);
+ /* use the first video as reference for everything */
+ sanim = seq->anims.first;
- if (!seq->anim) {
+ if ((!sanim) || (!sanim->anim)) {
return;
}
- 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);
+ seq->len = IMB_anim_get_duration(sanim->anim, seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN);
+
+ seq->anim_preseek = IMB_anim_get_preseek(sanim->anim);
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
@@ -810,6 +908,7 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, const bool lock_r
seq->len = 0;
}
break;
+ }
case SEQ_TYPE_MOVIECLIP:
if (seq->clip == NULL)
return;
@@ -876,7 +975,6 @@ void BKE_sequencer_sort(Scene *scene)
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seqt;
-
if (ed == NULL)
return;
@@ -1017,6 +1115,7 @@ static const char *give_seqname_by_type(int type)
case SEQ_TYPE_ADJUSTMENT: return "Adjustment";
case SEQ_TYPE_SPEED: return "Speed";
case SEQ_TYPE_GAUSSIAN_BLUR: return "Gaussian Blur";
+ case SEQ_TYPE_TEXT: return "Text";
default:
return NULL;
}
@@ -1027,7 +1126,7 @@ const char *BKE_sequence_give_name(Sequence *seq)
const char *name = give_seqname_by_type(seq->type);
if (!name) {
- if (seq->type < SEQ_TYPE_EFFECT) {
+ if (!(seq->type & SEQ_TYPE_EFFECT)) {
return seq->strip->dir;
}
else {
@@ -1063,30 +1162,25 @@ static void make_black_ibuf(ImBuf *ibuf)
}
}
-static void multibuf(ImBuf *ibuf, float fmul)
+static void multibuf(ImBuf *ibuf, const float fmul)
{
char *rt;
float *rt_float;
- int a, mul, icol;
+ int a;
- mul = (int)(256.0f * fmul);
rt = (char *)ibuf->rect;
rt_float = ibuf->rect_float;
if (rt) {
+ const int imul = (int)(256.0f * fmul);
a = ibuf->x * ibuf->y;
while (a--) {
+ rt[0] = min_ii((imul * rt[0]) >> 8, 255);
+ rt[1] = min_ii((imul * rt[1]) >> 8, 255);
+ rt[2] = min_ii((imul * rt[2]) >> 8, 255);
+ rt[3] = min_ii((imul * rt[3]) >> 8, 255);
- icol = (mul * rt[0]) >> 8;
- if (icol > 254) rt[0] = 255; else rt[0] = icol;
- icol = (mul * rt[1]) >> 8;
- if (icol > 254) rt[1] = 255; else rt[1] = icol;
- icol = (mul * rt[2]) >> 8;
- if (icol > 254) rt[2] = 255; else rt[2] = icol;
- icol = (mul * rt[3]) >> 8;
- if (icol > 254) rt[3] = 255; else rt[3] = icol;
-
rt += 4;
}
}
@@ -1168,7 +1262,7 @@ static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfr
seq = seqbase->first;
while (seq) {
if (seq->startdisp <= cfra && seq->enddisp > cfra) {
- if ((seq->type & SEQ_TYPE_EFFECT)) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SEQ_MUTE)) {
if (seq->seq1) {
effect_inputs[num_effect_inputs++] = seq->seq1;
}
@@ -1277,6 +1371,8 @@ typedef struct SeqIndexBuildContext {
int tc_flags;
int size_flags;
int quality;
+ bool overwrite;
+ size_t view_id;
Main *bmain;
Scene *scene;
@@ -1316,48 +1412,164 @@ static double seq_rendersize_to_scale_factor(int size)
return 0.25;
}
-static void seq_open_anim_file(Sequence *seq)
+/* the number of files will vary according to the stereo format */
+static size_t seq_num_files(Scene *scene, char views_format, const bool is_multiview)
+{
+ if (!is_multiview) {
+ return 1;
+ }
+ else if (views_format == R_IMF_VIEWS_STEREO_3D) {
+ return 1;
+ }
+ /* R_IMF_VIEWS_INDIVIDUAL */
+ else {
+ return BKE_scene_multiview_num_views_get(&scene->r);
+ }
+}
+
+static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir)
+{
+ char dir[FILE_MAX];
+ char fname[FILE_MAXFILE];
+
+ IMB_anim_get_fname(anim, fname, FILE_MAXFILE);
+ BLI_strncpy(dir, base_dir, sizeof(dir));
+ BLI_path_append(dir, sizeof(dir), fname);
+ IMB_anim_set_index_dir(anim, dir);
+}
+
+static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
{
+ char dir[FILE_MAX];
char name[FILE_MAX];
StripProxy *proxy;
+ bool use_proxy;
+ bool is_multiview_loaded = false;
+ Editing *ed = scene->ed;
+ const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 && (scene->r.scemode & R_MULTIVIEW) != 0;
- if (seq->anim != NULL) {
+ if ((seq->anims.first != NULL) && (((StripAnim *)seq->anims.first)->anim != NULL)) {
return;
}
+ /* reset all the previously created anims */
+ BKE_sequence_free_anim(seq);
+
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, seq->strip->colorspace_settings.name);
- if (seq->anim == NULL) {
- return;
+ proxy = seq->strip->proxy;
+
+ use_proxy = proxy && ((proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) != 0 ||
+ (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE));
+
+ if (use_proxy) {
+ if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
+ if (ed->proxy_dir[0] == 0)
+ BLI_strncpy(dir, "//BL_proxy", sizeof(dir));
+ else
+ BLI_strncpy(dir, ed->proxy_dir, sizeof(dir));
+ }
+ else {
+ BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
+ }
+ BLI_path_abs(dir, G.main->name);
}
- proxy = seq->strip->proxy;
+ if (is_multiview && seq->views_format == R_IMF_VIEWS_INDIVIDUAL) {
+ size_t totfiles = seq_num_files(scene, seq->views_format, true);
+ char prefix[FILE_MAX];
+ const char *ext = NULL;
+ int i;
- if (proxy == NULL) {
- return;
+ BKE_scene_multiview_view_prefix_get(scene, name, prefix, &ext);
+
+ if (prefix[0] != '\0') {
+ for (i = 0; i < totfiles; i++) {
+ const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
+ char str[FILE_MAX];
+ StripAnim *sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+
+ BLI_addtail(&seq->anims, sanim);
+
+ BLI_snprintf(str, sizeof(str), "%s%s%s", prefix, suffix, ext);
+
+ if (openfile) {
+ sanim->anim = openanim(
+ str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+ else {
+ sanim->anim = openanim_noload(
+ str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+
+ if (sanim->anim) {
+#if 0
+ seq_anim_add_suffix(scene, sanim->anim, i);
+#else
+ /* we already have the suffix */
+ IMB_suffix_anim(sanim->anim, suffix);
+#endif
+ }
+ else {
+ if (openfile) {
+ sanim->anim = openanim(
+ name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+ else {
+ sanim->anim = openanim_noload(
+ name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+
+ /* no individual view files - monoscopic, stereo 3d or exr multiview */
+ totfiles = 1;
+ }
+
+ if (sanim->anim && use_proxy) {
+ seq_proxy_index_dir_set(sanim->anim, dir);
+ }
+ }
+ is_multiview_loaded = true;
+ }
}
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
- char dir[FILE_MAX];
- BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
- BLI_path_abs(dir, G.main->name);
+ if (is_multiview_loaded == false) {
+ StripAnim *sanim;
+
+ sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
- IMB_anim_set_index_dir(seq->anim, dir);
+ if (openfile) {
+ sanim->anim = openanim(
+ name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+ else {
+ sanim->anim = openanim_noload(
+ name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+
+ if (sanim->anim && use_proxy) {
+ seq_proxy_index_dir_set(sanim->anim, dir);
+ }
}
}
-
-static bool seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *name)
+static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render_size, char *name, const size_t view_id)
{
int frameno;
char dir[PROXY_MAXFILE];
+ StripAnim *sanim;
+ char suffix[24] = {'\0'};
- if (!seq->strip->proxy) {
+ StripProxy *proxy = seq->strip->proxy;
+ if (!proxy) {
return false;
}
@@ -1369,20 +1581,53 @@ static bool seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *
* 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)) {
+ sanim = BLI_findlink(&seq->anims, view_id);
+
+ if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
+ char fname[FILE_MAXFILE];
+ if (ed->proxy_dir[0] == 0)
+ BLI_strncpy(dir, "//BL_proxy", sizeof(dir));
+ else
+ BLI_strncpy(dir, ed->proxy_dir, sizeof(dir));
+
+ if (sanim && sanim->anim) {
+ IMB_anim_get_fname(sanim->anim, fname, FILE_MAXFILE);
+ }
+ else if (seq->type == SEQ_TYPE_IMAGE) {
+ fname[0] = 0;
+ }
+ BLI_path_append(dir, sizeof(dir), fname);
+ BLI_path_abs(name, G.main->name);
+ }
+ else if ((proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) && (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE)) {
BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
}
+ else if (sanim && sanim->anim && (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR)) {
+ char fname[FILE_MAXFILE];
+ BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
+ IMB_anim_get_fname(sanim->anim, fname, FILE_MAXFILE);
+ BLI_path_append(dir, sizeof(dir), fname);
+ }
else if (seq->type == SEQ_TYPE_IMAGE) {
- BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
+ if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR)
+ BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
+ else
+ BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
}
else {
return false;
}
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
+ if (view_id > 0)
+ BLI_snprintf(suffix, sizeof(suffix), "_%zu", view_id);
+
+ if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE && sanim && sanim->anim &&
+ ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE)
+ {
BLI_join_dirfile(name, PROXY_MAXFILE,
- dir, seq->strip->proxy->file);
+ dir, proxy->file);
BLI_path_abs(name, G.main->name);
+ BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", name, suffix);
return true;
}
@@ -1390,13 +1635,13 @@ static bool seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *
/* generate a separate proxy directory for each preview size */
if (seq->type == SEQ_TYPE_IMAGE) {
- BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir, render_size,
- BKE_sequencer_give_stripelem(seq, cfra)->name);
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy%s", dir, render_size,
+ BKE_sequencer_give_stripelem(seq, cfra)->name, suffix);
frameno = 1;
}
else {
frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs;
- BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, render_size);
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####%s", dir, render_size, suffix);
}
BLI_path_abs(name, G.main->name);
@@ -1413,45 +1658,48 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
int size_flags;
int render_size = context->preview_render_size;
+ StripProxy *proxy = seq->strip->proxy;
+ Editing *ed = context->scene->ed;
+ StripAnim *sanim;
+
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return NULL;
+ }
/* dirty hack to distinguish 100% render size from PROXY_100 */
if (render_size == 99) {
render_size = 100;
}
- if (!(seq->flag & SEQ_USE_PROXY)) {
- return NULL;
- }
-
- size_flags = seq->strip->proxy->build_size_flags;
+ size_flags = 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;
}
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
+ if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
int frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs;
- if (seq->strip->proxy->anim == NULL) {
- if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
+ if (proxy->anim == NULL) {
+ if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) {
return NULL;
}
- /* proxies are generated in default color space */
- seq->strip->proxy->anim = openanim(name, IB_rect, 0, NULL);
+ proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name);
}
- if (seq->strip->proxy->anim == NULL) {
+ if (proxy->anim == NULL) {
return NULL;
}
- seq_open_anim_file(seq);
+ seq_open_anim_file(context->scene, seq, true);
+ sanim = seq->anims.first;
- frameno = IMB_anim_index_get_frame_index(seq->anim, seq->strip->proxy->tc, frameno);
+ frameno = IMB_anim_index_get_frame_index(sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno);
- return IMB_anim_absolute(seq->strip->proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
+ return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
- if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
+ if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) {
return NULL;
}
@@ -1468,31 +1716,44 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
}
}
-static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra, int proxy_render_size)
+static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra,
+ int proxy_render_size, const bool overwrite)
{
char name[PROXY_MAXFILE];
int quality;
int rectx, recty;
int ok;
- ImBuf *ibuf;
+ ImBuf *ibuf_tmp, *ibuf;
+ Editing *ed = context->scene->ed;
- if (!seq_proxy_get_fname(seq, cfra, proxy_render_size, name)) {
+ if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) {
return;
}
- ibuf = seq_render_strip(context, seq, cfra);
+ if (!overwrite && BLI_exists(name)) {
+ return;
+ }
+
+ ibuf_tmp = seq_render_strip(context, seq, cfra);
- rectx = (proxy_render_size * ibuf->x) / 100;
- recty = (proxy_render_size * ibuf->y) / 100;
+ rectx = (proxy_render_size * ibuf_tmp->x) / 100;
+ recty = (proxy_render_size * ibuf_tmp->y) / 100;
- if (ibuf->x != rectx || ibuf->y != recty) {
+ if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) {
+ ibuf = IMB_dupImBuf(ibuf_tmp);
+ IMB_metadata_copy(ibuf, ibuf_tmp);
+ IMB_freeImBuf(ibuf_tmp);
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
}
+ else {
+ ibuf = ibuf_tmp;
+ }
/* depth = 32 is intentionally left in, otherwise ALPHA channels
* won't work... */
quality = seq->strip->proxy->quality;
- ibuf->ftype = JPG | quality;
+ ibuf->ftype = IMB_FTYPE_JPG;
+ ibuf->foptions.quality = quality;
/* unsupported feature only confuses other s/w */
if (ibuf->planes == 32)
@@ -1508,46 +1769,138 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
IMB_freeImBuf(ibuf);
}
-SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq)
+/* returns whether the file this context would read from even exist, if not, don't create the context
+*/
+static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const size_t view_id)
+{
+ if ((scene->r.scemode & R_MULTIVIEW) == 0)
+ return false;
+
+ if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
+ static char prefix[FILE_MAX];
+ static const char *ext = NULL;
+ char str[FILE_MAX];
+
+ if (view_id == 0) {
+ char path[FILE_MAX];
+ BLI_join_dirfile(path, sizeof(path), seq->strip->dir,
+ seq->strip->stripdata->name);
+ BLI_path_abs(path, G.main->name);
+ BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
+ }
+ else {
+ prefix[0] = '\0';
+ }
+
+ if (prefix[0] == '\0')
+ return view_id != 0;
+
+ seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX);
+
+ if (BLI_access(str, R_OK) == 0)
+ return false;
+ else
+ return view_id != 0;
+ }
+ return false;
+}
+
+/** This returns the maximum possible number of required contexts
+*/
+static size_t seq_proxy_context_count(Sequence *seq, Scene *scene)
+{
+ size_t num_views = 1;
+
+ if ((scene->r.scemode & R_MULTIVIEW) == 0)
+ return 1;
+
+ switch (seq->type) {
+ case SEQ_TYPE_MOVIE:
+ {
+ num_views = BLI_listbase_count(&seq->anims);
+ break;
+ }
+ case SEQ_TYPE_IMAGE:
+ {
+ switch (seq->views_format) {
+ case R_IMF_VIEWS_INDIVIDUAL:
+ num_views = BKE_scene_multiview_num_views_get(&scene->r);
+ break;
+ case R_IMF_VIEWS_STEREO_3D:
+ num_views = 2;
+ break;
+ case R_IMF_VIEWS_MULTIVIEW:
+ /* not supported at the moment */
+ /* pass through */
+ default:
+ num_views = 1;
+ }
+ break;
+ }
+ }
+
+ return num_views;
+}
+
+void BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq, struct GSet *file_list, ListBase *queue)
{
SeqIndexBuildContext *context;
Sequence *nseq;
+ LinkData *link;
+ size_t i;
+ size_t num_files;
if (!seq->strip || !seq->strip->proxy) {
- return NULL;
+ return;
}
if (!(seq->flag & SEQ_USE_PROXY)) {
- return NULL;
+ return;
}
- context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
+ num_files = seq_proxy_context_count(seq, scene);
+
+ for (i = 0; i < num_files; i++) {
+ if (seq_proxy_multiview_context_invalid(seq, scene, i))
+ continue;
- nseq = BKE_sequence_dupli_recursive(scene, scene, seq, 0);
+ context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
- context->tc_flags = nseq->strip->proxy->build_tc_flags;
- context->size_flags = nseq->strip->proxy->build_size_flags;
- context->quality = nseq->strip->proxy->quality;
+ nseq = BKE_sequence_dupli_recursive(scene, scene, seq, 0);
- context->bmain = bmain;
- context->scene = scene;
- context->orig_seq = seq;
- context->seq = nseq;
+ context->tc_flags = nseq->strip->proxy->build_tc_flags;
+ context->size_flags = nseq->strip->proxy->build_size_flags;
+ context->quality = nseq->strip->proxy->quality;
+ context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0;
- if (nseq->type == SEQ_TYPE_MOVIE) {
- seq_open_anim_file(nseq);
+ context->bmain = bmain;
+ context->scene = scene;
+ context->orig_seq = seq;
+ context->seq = nseq;
- if (nseq->anim) {
- context->index_context = IMB_anim_index_rebuild_context(nseq->anim,
- context->tc_flags, context->size_flags, context->quality);
+ context->view_id = i; /* only for images */
+
+ link = BLI_genericNodeN(context);
+ BLI_addtail(queue, link);
+
+ if (nseq->type == SEQ_TYPE_MOVIE) {
+ StripAnim *sanim;
+
+ seq_open_anim_file(scene, nseq, true);
+ sanim = BLI_findlink(&nseq->anims, i);
+
+ if (sanim->anim) {
+ context->index_context = IMB_anim_index_rebuild_context(sanim->anim,
+ context->tc_flags, context->size_flags, context->quality,
+ context->overwrite, file_list);
+ }
}
}
-
- return context;
}
void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, short *do_update, float *progress)
{
+ const bool overwrite = context->overwrite;
SeqRenderData render_context;
Sequence *seq = context->seq;
Scene *scene = context->scene;
@@ -1567,30 +1920,34 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
}
/* that's why it is called custom... */
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
+ if (seq->strip->proxy && seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
return;
}
/* fail safe code */
- render_context = BKE_sequencer_new_render_data(bmain->eval_ctx, bmain, context->scene,
- (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
- (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100);
+ BKE_sequencer_new_render_data(
+ bmain->eval_ctx, bmain, context->scene,
+ (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
+ (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100,
+ &render_context);
+
render_context.skip_cache = true;
render_context.is_proxy_render = true;
+ render_context.view_id = context->view_id;
for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
if (context->size_flags & IMB_PROXY_25) {
- seq_proxy_build_frame(&render_context, seq, cfra, 25);
+ seq_proxy_build_frame(&render_context, seq, cfra, 25, overwrite);
}
if (context->size_flags & IMB_PROXY_50) {
- seq_proxy_build_frame(&render_context, seq, cfra, 50);
+ seq_proxy_build_frame(&render_context, seq, cfra, 50, overwrite);
}
if (context->size_flags & IMB_PROXY_75) {
- seq_proxy_build_frame(&render_context, seq, cfra, 75);
+ seq_proxy_build_frame(&render_context, seq, cfra, 75, overwrite);
}
if (context->size_flags & IMB_PROXY_100) {
- seq_proxy_build_frame(&render_context, seq, cfra, 100);
+ seq_proxy_build_frame(&render_context, seq, cfra, 100, overwrite);
}
*progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
@@ -1604,8 +1961,14 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop)
{
if (context->index_context) {
- IMB_close_anim_proxies(context->seq->anim);
- IMB_close_anim_proxies(context->orig_seq->anim);
+ StripAnim *sanim;
+
+ for (sanim = context->seq->anims.first; sanim; sanim = sanim->next)
+ IMB_close_anim_proxies(sanim->anim);
+
+ for (sanim = context->orig_seq->anims.first; sanim; sanim = sanim->next)
+ IMB_close_anim_proxies(sanim->anim);
+
IMB_anim_index_rebuild_finish(context->index_context, stop);
}
@@ -1614,6 +1977,22 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop
MEM_freeN(context);
}
+void BKE_sequencer_proxy_set(struct Sequence *seq, bool value)
+{
+ if (value) {
+ seq->flag |= SEQ_USE_PROXY;
+ if (seq->strip->proxy == NULL) {
+ seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
+ seq->strip->proxy->quality = 90;
+ seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL;
+ seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25;
+ }
+ }
+ else {
+ seq->flag ^= SEQ_USE_PROXY;
+ }
+}
+
/*********************** color balance *************************/
static StripColorBalance calc_cb(StripColorBalance *cb_)
@@ -1868,7 +2247,10 @@ static void *color_balance_do_thread(void *thread_data_v)
return NULL;
}
-ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, bool make_float)
+/* cfra is offset by fra_offset only in case we are using a real mask. */
+ImBuf *BKE_sequencer_render_mask_input(
+ const SeqRenderData *context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id,
+ int cfra, int fra_offset, bool make_float)
{
ImBuf *mask_input = NULL;
@@ -1887,7 +2269,7 @@ ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, int mask_in
}
}
else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
- mask_input = seq_render_mask(context, mask_id, cfra, make_float);
+ mask_input = seq_render_mask(context, mask_id, cfra - fra_offset, make_float);
}
return mask_input;
@@ -2047,6 +2429,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context, Sequence *seq, floa
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
sequencer_imbuf_assign_spaces(scene, i);
+ IMB_metadata_copy(i, ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
@@ -2098,6 +2481,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context, Sequence *seq, floa
ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra);
if (ibuf_new != ibuf) {
+ IMB_metadata_copy(ibuf_new, ibuf);
IMB_freeImBuf(ibuf);
ibuf = ibuf_new;
}
@@ -2120,6 +2504,7 @@ static ImBuf *copy_from_ibuf_still(const SeqRenderData *context, Sequence *seq,
if (ibuf) {
rval = IMB_dupImBuf(ibuf);
+ IMB_metadata_copy(rval, ibuf);
IMB_freeImBuf(ibuf);
}
@@ -2133,9 +2518,11 @@ static void copy_to_ibuf_still(const SeqRenderData *context, Sequence *seq, floa
/* we have to store a copy, since the passed ibuf
* could be preprocessed afterwards (thereby silently
* changing the cached image... */
- ibuf = IMB_dupImBuf(ibuf);
+ ImBuf *oibuf = ibuf;
+ ibuf = IMB_dupImBuf(oibuf);
if (ibuf) {
+ IMB_metadata_copy(ibuf, oibuf);
sequencer_imbuf_assign_spaces(context->scene, ibuf);
}
@@ -2331,6 +2718,237 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, Sequenc
return out;
}
+static ImBuf *seq_render_image_strip(const SeqRenderData *context, Sequence *seq, float nr, float cfra)
+{
+ ImBuf *ibuf = NULL;
+ char name[FILE_MAX];
+ bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
+ (context->scene->r.scemode & R_MULTIVIEW) != 0;
+ StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
+ int flag;
+
+ if (s_elem) {
+ BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
+ BLI_path_abs(name, G.main->name);
+ }
+
+ flag = IB_rect | IB_metadata;
+ if (seq->alpha_mode == SEQ_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ if (!s_elem) {
+ /* don't do anything */
+ }
+ else if (is_multiview) {
+ size_t totfiles = seq_num_files(context->scene, seq->views_format, true);
+ size_t totviews;
+ struct ImBuf **ibufs_arr;
+ char prefix[FILE_MAX];
+ const char *ext = NULL;
+ int i;
+
+ if (totfiles > 1) {
+ BKE_scene_multiview_view_prefix_get(context->scene, name, prefix, &ext);
+ if (prefix[0] == '\0') {
+ goto monoview_image;
+ }
+ }
+ else {
+ prefix[0] = '\0';
+ }
+
+ totviews = BKE_scene_multiview_num_views_get(&context->scene->r);
+ ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
+
+ for (i = 0; i < totfiles; i++) {
+
+ if (prefix[0] == '\0') {
+ ibufs_arr[i] = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name);
+ }
+ else {
+ char str[FILE_MAX];
+ seq_multiview_name(context->scene, i, prefix, ext, str, FILE_MAX);
+ ibufs_arr[i] = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name);
+ }
+
+ if (ibufs_arr[i]) {
+ /* we don't need both (speed reasons)! */
+ if (ibufs_arr[i]->rect_float && ibufs_arr[i]->rect)
+ imb_freerectImBuf(ibufs_arr[i]);
+ }
+ }
+
+ if (seq->views_format == R_IMF_VIEWS_STEREO_3D && ibufs_arr[0])
+ IMB_ImBufFromStereo3d(seq->stereo3d_format, ibufs_arr[0], &ibufs_arr[0], &ibufs_arr[1]);
+
+ for (i = 0; i < totviews; i++) {
+ if (ibufs_arr[i]) {
+ SeqRenderData localcontext = *context;
+ localcontext.view_id = i;
+
+ /* all sequencer color is done in SRGB space, linear gives odd crossfades */
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[i], false);
+
+ if (i != context->view_id) {
+ copy_to_ibuf_still(&localcontext, seq, nr, ibufs_arr[i]);
+ BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibufs_arr[i]);
+ }
+ }
+ }
+
+ /* return the original requested ImBuf */
+ ibuf = ibufs_arr[context->view_id];
+ if (ibuf) {
+ s_elem->orig_width = ibufs_arr[0]->x;
+ s_elem->orig_height = ibufs_arr[0]->y;
+ }
+
+ /* "remove" the others (decrease their refcount) */
+ for (i = 0; i < totviews; i++) {
+ if (ibufs_arr[i] != ibuf) {
+ IMB_freeImBuf(ibufs_arr[i]);
+ }
+ }
+
+ MEM_freeN(ibufs_arr);
+ }
+ else {
+monoview_image:
+ if ((ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name))) {
+ /* 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 */
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
+
+ s_elem->orig_width = ibuf->x;
+ s_elem->orig_height = ibuf->y;
+ }
+ }
+
+ return ibuf;
+}
+
+static ImBuf *seq_render_movie_strip(const SeqRenderData *context, Sequence *seq, float nr, float cfra)
+{
+ ImBuf *ibuf = NULL;
+ StripAnim *sanim;
+ bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
+ (context->scene->r.scemode & R_MULTIVIEW) != 0;
+
+ /* load all the videos */
+ seq_open_anim_file(context->scene, seq, false);
+
+ if (is_multiview) {
+ ImBuf **ibuf_arr;
+ size_t totviews;
+ size_t totfiles = seq_num_files(context->scene, seq->views_format, true);
+ int i;
+
+ if (totfiles != BLI_listbase_count_ex(&seq->anims, totfiles + 1))
+ goto monoview_movie;
+
+ totviews = BKE_scene_multiview_num_views_get(&context->scene->r);
+ ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
+
+ for (i = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, i++) {
+ if (sanim->anim) {
+ IMB_Proxy_Size proxy_size = seq_rendersize_to_proxysize(context->preview_render_size);
+ IMB_anim_set_preseek(sanim->anim, seq->anim_preseek);
+
+ ibuf_arr[i] = IMB_anim_absolute(sanim->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ proxy_size);
+
+ /* fetching for requested proxy size failed, try fetching the original instead */
+ if (!ibuf_arr[i] && proxy_size != IMB_PROXY_NONE) {
+ ibuf_arr[i] = IMB_anim_absolute(sanim->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ IMB_PROXY_NONE);
+ }
+ if (ibuf_arr[i]) {
+ /* we don't need both (speed reasons)! */
+ if (ibuf_arr[i]->rect_float && ibuf_arr[i]->rect)
+ imb_freerectImBuf(ibuf_arr[i]);
+ }
+ }
+ }
+
+ if (seq->views_format == R_IMF_VIEWS_STEREO_3D) {
+ if (ibuf_arr[0]) {
+ IMB_ImBufFromStereo3d(seq->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
+ }
+ else {
+ /* probably proxy hasn't been created yet */
+ MEM_freeN(ibuf_arr);
+ return NULL;
+ }
+ }
+
+ for (i = 0; i < totviews; i++) {
+ SeqRenderData localcontext = *context;
+ localcontext.view_id = i;
+
+ if (ibuf_arr[i]) {
+ /* all sequencer color is done in SRGB space, linear gives odd crossfades */
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf_arr[i], false);
+ }
+ if (i != context->view_id) {
+ copy_to_ibuf_still(&localcontext, seq, nr, ibuf_arr[i]);
+ BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf_arr[i]);
+ }
+ }
+
+ /* return the original requested ImBuf */
+ ibuf = ibuf_arr[context->view_id];
+ if (ibuf) {
+ seq->strip->stripdata->orig_width = ibuf->x;
+ seq->strip->stripdata->orig_height = ibuf->y;
+ }
+
+ /* "remove" the others (decrease their refcount) */
+ for (i = 0; i < totviews; i++) {
+ if (ibuf_arr[i] != ibuf) {
+ IMB_freeImBuf(ibuf_arr[i]);
+ }
+ }
+
+ MEM_freeN(ibuf_arr);
+ }
+ else {
+monoview_movie:
+ sanim = seq->anims.first;
+ if (sanim && sanim->anim) {
+ IMB_Proxy_Size proxy_size = seq_rendersize_to_proxysize(context->preview_render_size);
+ IMB_anim_set_preseek(sanim->anim, seq->anim_preseek);
+
+ ibuf = IMB_anim_absolute(sanim->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ proxy_size);
+
+ /* fetching for requested proxy size failed, try fetching the original instead */
+ if (!ibuf && proxy_size != IMB_PROXY_NONE) {
+ ibuf = IMB_anim_absolute(sanim->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ IMB_PROXY_NONE);
+ }
+ if (ibuf) {
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
+
+ /* we don't need both (speed reasons)! */
+ if (ibuf->rect_float && ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ }
+
+ seq->strip->stripdata->orig_width = ibuf->x;
+ seq->strip->stripdata->orig_height = ibuf->y;
+ }
+ }
+ }
+ return ibuf;
+}
+
static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context, Sequence *seq, float nr)
{
ImBuf *ibuf = NULL;
@@ -2462,13 +3080,20 @@ static ImBuf *seq_render_mask_strip(const SeqRenderData *context, Sequence *seq,
return seq_render_mask(context, seq->mask, nr, make_float);
}
-static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq, float nr)
+static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq, float nr, float cfra)
{
ImBuf *ibuf = NULL;
- float frame;
- float oldcfra;
+ double frame;
Object *camera;
- ListBase oldmarkers;
+
+ struct {
+ int scemode;
+ int cfra;
+ float subframe;
+#ifdef DURIAN_CAMERA_SWITCH
+ ListBase markers;
+#endif
+ } orig_data;
/* Old info:
* Hack! This function can be called from do_render_seq(), in that case
@@ -2506,9 +3131,11 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
const bool do_seq_gl = is_rendering ?
0 /* (context->scene->r.seq_flag & R_SEQ_GL_REND) */ :
(context->scene->r.seq_flag & R_SEQ_GL_PREV) != 0;
- int do_seq;
// bool have_seq = false; /* UNUSED */
bool have_comp = false;
+ bool use_gpencil = true;
+ /* do we need to re-evaluate the frame after rendering? */
+ bool is_frame_update = false;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2518,13 +3145,19 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
}
scene = seq->scene;
- frame = scene->r.sfra + nr + seq->anim_startofs;
+ frame = (double)scene->r.sfra + (double)nr + (double)seq->anim_startofs;
// have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first); /* UNUSED */
have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
- oldcfra = scene->r.cfra;
- scene->r.cfra = frame;
+ orig_data.scemode = scene->r.scemode;
+ orig_data.cfra = scene->r.cfra;
+ orig_data.subframe = scene->r.subframe;
+#ifdef DURIAN_CAMERA_SWITCH
+ orig_data.markers = scene->markers;
+#endif
+
+ BKE_scene_frame_set(scene, frame);
if (seq->scene_camera) {
camera = seq->scene_camera;
@@ -2533,28 +3166,30 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
BKE_scene_camera_switch_update(scene);
camera = scene->camera;
}
-
+
if (have_comp == false && camera == NULL) {
- scene->r.cfra = oldcfra;
- return NULL;
+ goto finally;
+ }
+
+ if (seq->flag & SEQ_SCENE_NO_GPENCIL) {
+ use_gpencil = false;
}
/* prevent eternal loop */
- do_seq = scene->r.scemode & R_DOSEQ;
scene->r.scemode &= ~R_DOSEQ;
#ifdef DURIAN_CAMERA_SWITCH
/* stooping to new low's in hackyness :( */
- oldmarkers = scene->markers;
BLI_listbase_clear(&scene->markers);
-#else
- (void)oldmarkers;
#endif
+ is_frame_update = (orig_data.cfra != scene->r.cfra) || (orig_data.subframe != scene->r.subframe);
+
if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) {
char err_out[256] = "unknown";
int width = (scene->r.xsch * scene->r.size) / 100;
int height = (scene->r.ysch * scene->r.size) / 100;
+ const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id);
/* for old scened this can be uninitialized,
* should probably be added to do_versions at some point if the functionality stays */
@@ -2566,14 +3201,18 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect,
context->scene->r.seq_prev_type,
(context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
- true, scene->r.alphamode, err_out);
+ use_gpencil, true, scene->r.alphamode, viewname, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
}
else {
Render *re = RE_GetRender(scene->id.name);
- RenderResult rres;
+ size_t totviews = BKE_scene_multiview_num_views_get(&scene->r);
+ int i;
+ ImBuf **ibufs_arr;
+
+ ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
/* XXX: this if can be removed when sequence preview rendering uses the job system
*
@@ -2583,7 +3222,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
* When rendering from command line renderer is called from main thread, in this
* case it's always safe to render scene here
*/
- if (!is_thread_main || is_rendering == false || is_background) {
+ if (!is_thread_main || is_rendering == false || is_background || context->eval_ctx->mode == DAG_EVAL_RENDER) {
if (re == NULL)
re = RE_NewRender(scene->id.name);
@@ -2593,42 +3232,68 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
G.is_rendering = is_rendering;
}
-
- RE_AcquireResultImage(re, &rres);
-
- if (rres.rectf) {
- ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
- 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);
+
+ for (i = 0; i < totviews; i++) {
+ SeqRenderData localcontext = *context;
+ RenderResult rres;
+
+ localcontext.view_id = i;
+
+ RE_AcquireResultImage(re, &rres, i);
+
+ if (rres.rectf) {
+ ibufs_arr[i] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
+ memcpy(ibufs_arr[i]->rect_float, rres.rectf, 4 * sizeof(float) * rres.rectx * rres.recty);
+
+ if (rres.rectz) {
+ addzbuffloatImBuf(ibufs_arr[i]);
+ memcpy(ibufs_arr[i]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty);
+ }
+
+ /* float buffers in the sequencer are not linear */
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[i], false);
+ }
+ else if (rres.rect32) {
+ ibufs_arr[i] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
+ memcpy(ibufs_arr[i]->rect, rres.rect32, 4 * rres.rectx * rres.recty);
}
- /* float buffers in the sequencer are not linear */
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
+ if (i != context->view_id) {
+ copy_to_ibuf_still(&localcontext, seq, nr, ibufs_arr[i]);
+ BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibufs_arr[i]);
+ }
+
+ RE_ReleaseResultImage(re);
}
- else if (rres.rect32) {
- ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
- memcpy(ibuf->rect, rres.rect32, 4 * rres.rectx * rres.recty);
+
+ /* return the original requested ImBuf */
+ ibuf = ibufs_arr[context->view_id];
+
+ /* "remove" the others (decrease their refcount) */
+ for (i = 0; i < totviews; i++) {
+ if (ibufs_arr[i] != ibuf) {
+ IMB_freeImBuf(ibufs_arr[i]);
+ }
}
-
- RE_ReleaseResultImage(re);
-
+ MEM_freeN(ibufs_arr);
+
// BIF_end_render_callbacks();
}
-
+
+
+finally:
/* restore */
- scene->r.scemode |= do_seq;
-
- scene->r.cfra = oldcfra;
+ scene->r.scemode = orig_data.scemode;
+ scene->r.cfra = orig_data.cfra;
+ scene->r.subframe = orig_data.subframe;
- if (frame != oldcfra) {
+ if (is_frame_update) {
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene, scene->lay);
}
-
+
#ifdef DURIAN_CAMERA_SWITCH
/* stooping to new low's in hackyness :( */
- scene->markers = oldmarkers;
+ scene->markers = orig_data.markers;
#endif
return ibuf;
@@ -2640,7 +3305,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
float nr = give_stripelem_index(seq, cfra);
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
bool use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
- char name[FILE_MAX];
switch (type) {
case SEQ_TYPE_META:
@@ -2699,57 +3363,14 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
case SEQ_TYPE_IMAGE:
{
- StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
- int flag;
-
- if (s_elem) {
- BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
- BLI_path_abs(name, G.main->name);
- }
-
- flag = IB_rect;
- if (seq->alpha_mode == SEQ_ALPHA_PREMUL)
- flag |= IB_alphamode_premul;
-
- if (s_elem && (ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name))) {
- /* 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 */
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
-
- copy_to_ibuf_still(context, seq, nr, ibuf);
-
- s_elem->orig_width = ibuf->x;
- s_elem->orig_height = ibuf->y;
- }
+ ibuf = seq_render_image_strip(context, seq, nr, cfra);
+ copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MOVIE:
{
- 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,
- seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
- seq_rendersize_to_proxysize(context->preview_render_size));
-
- if (ibuf) {
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
-
- /* we don't need both (speed reasons)! */
- if (ibuf->rect_float && ibuf->rect) {
- imb_freerectImBuf(ibuf);
- }
-
- seq->strip->stripdata->orig_width = ibuf->x;
- seq->strip->stripdata->orig_height = ibuf->y;
- }
- }
+ ibuf = seq_render_movie_strip(context, seq, nr, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
@@ -2757,7 +3378,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
case SEQ_TYPE_SCENE:
{
/* scene can be NULL after deletions */
- ibuf = seq_render_scene_strip(context, seq, nr);
+ ibuf = seq_render_scene_strip(context, seq, nr, cfra);
/* Scene strips update all animation, so we need to restore original state.*/
BKE_animsys_evaluate_all_animation(context->bmain, context->scene, cfra);
@@ -2986,6 +3607,8 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq
out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2);
+ IMB_metadata_copy(out, ibuf2);
+
IMB_freeImBuf(ibuf1);
IMB_freeImBuf(ibuf2);
}
@@ -3080,7 +3703,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha
if (ed == NULL) return NULL;
if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) {
- int count = BLI_countlist(&ed->metastack);
+ int count = BLI_listbase_count(&ed->metastack);
count = max_ii(count + chanshown, 0);
seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
}
@@ -3254,16 +3877,6 @@ ImBuf *BKE_sequencer_give_ibuf_threaded(const SeqRenderData *context, float cfra
return e ? e->ibuf : NULL;
}
-/* Functions to free imbuf and anim data on changes */
-
-static void free_anim_seq(Sequence *seq)
-{
- if (seq->anim) {
- IMB_free_anim(seq->anim);
- seq->anim = NULL;
- }
-}
-
/* check whether sequence cur depends on seq */
bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
{
@@ -3315,15 +3928,11 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, bool invalida
/* invalidate cache for current sequence */
if (invalidate_self) {
- if (seq->anim) {
- /* Animation structure holds some buffers inside,
- * so for proper cache invalidation we need to
- * re-open the animation.
- */
- IMB_free_anim(seq->anim);
- seq->anim = NULL;
- }
-
+ /* Animation structure holds some buffers inside,
+ * so for proper cache invalidation we need to
+ * re-open the animation.
+ */
+ BKE_sequence_free_anim(seq);
BKE_sequencer_cache_cleanup_sequence(seq);
}
@@ -3370,7 +3979,7 @@ void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
if (seq->strip) {
if (seq->type == SEQ_TYPE_MOVIE) {
- free_anim_seq(seq);
+ BKE_sequence_free_anim(seq);
}
if (seq->type == SEQ_TYPE_SPEED) {
BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
@@ -3395,7 +4004,7 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha
/* recurs downwards to see if this seq depends on the changed seq */
if (seq == NULL)
- return 0;
+ return false;
if (seq == changed_seq)
free_imbuf = true;
@@ -3417,7 +4026,7 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha
if (free_imbuf) {
if (ibuf_change) {
if (seq->type == SEQ_TYPE_MOVIE)
- free_anim_seq(seq);
+ BKE_sequence_free_anim(seq);
if (seq->type == SEQ_TYPE_SPEED) {
BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
}
@@ -3513,28 +4122,16 @@ bool BKE_sequence_single_check(Sequence *seq)
}
/* check if the selected seq's reference unselected seq's */
-bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase, bool one_only)
+bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
{
Sequence *seq;
- /* is there a valid selection select */
+ /* is there more than 1 select */
bool ok = false;
- /* is there one selected already? */
- bool first = false;
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- if (one_only) {
- ok = true;
- break;
- }
- else {
- if (first) {
- ok = true;
- break;
- }
- else
- first = true;
- }
+ ok = true;
+ break;
}
}
@@ -3632,7 +4229,7 @@ void BKE_sequence_single_fix(Sequence *seq)
bool BKE_sequence_tx_test(Sequence *seq)
{
- return (seq->type < SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0);
+ return !(seq->type & SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0);
}
static bool seq_overlap(Sequence *seq1, Sequence *seq2)
@@ -3681,10 +4278,10 @@ void BKE_sequence_sound_init(Scene *scene, Sequence *seq)
}
else {
if (seq->sound) {
- seq->scene_sound = sound_add_scene_sound_defaults(scene, seq);
+ seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
}
if (seq->scene) {
- seq->scene_sound = sound_scene_add_scene_sound_defaults(scene, seq);
+ seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq);
}
}
}
@@ -3712,21 +4309,23 @@ Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame)
}
/* return 0 if there werent enough space */
-bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep, Sequence *test, Scene *evil_scene, int channel_delta)
{
- int orig_machine = test->machine;
- test->machine++;
+ const int orig_machine = test->machine;
+ BLI_assert(ELEM(channel_delta, -1, 1));
+
+ test->machine += channel_delta;
BKE_sequence_calc(evil_scene, test);
- while (BKE_sequence_test_overlap(seqbasep, test) ) {
- if (test->machine >= MAXSEQ) {
+ while (BKE_sequence_test_overlap(seqbasep, test)) {
+ if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine <= 1)) {
break;
}
- test->machine++;
+
+ test->machine += channel_delta;
BKE_sequence_calc(evil_scene, test); // XXX - I don't think this is needed since were only moving vertically, Campbell.
}
-
- if (test->machine >= MAXSEQ) {
+ if ((test->machine < 1) || (test->machine > MAXSEQ)) {
/* Blender 2.4x would remove the strip.
* nicer to move it to the end */
@@ -3750,6 +4349,11 @@ bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_s
}
}
+bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+{
+ return BKE_sequence_base_shuffle_ex(seqbasep, test, evil_scene, 1);
+}
+
static int shuffle_seq_time_offset_test(ListBase *seqbasep, char dir)
{
int offset = 0;
@@ -3889,11 +4493,11 @@ void BKE_sequencer_update_sound_bounds(Scene *scene, Sequence *seq)
/* We have to take into account start frame of the sequence's scene! */
int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
- sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs);
+ BKE_sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs);
}
}
else {
- sound_move_scene_sound_defaults(scene, seq);
+ BKE_sound_move_scene_sound_defaults(scene, seq);
}
/* mute is set in seq_update_muting_recursive */
}
@@ -3918,7 +4522,7 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i
}
else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
if (seq->scene_sound) {
- sound_mute_scene_sound(seq->scene_sound, seqmute);
+ BKE_sound_mute_scene_sound(seq->scene_sound, seqmute);
}
}
}
@@ -3947,7 +4551,7 @@ static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound
}
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
if (seq->scene_sound && sound == seq->sound) {
- sound_update_scene_sound(seq->scene_sound, sound);
+ BKE_sound_update_scene_sound(seq->scene_sound, sound);
}
}
}
@@ -4062,7 +4666,7 @@ static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char
char name_esc[SEQ_NAME_MAXSTR * 2];
BLI_strescape(name_esc, name, sizeof(name_esc));
- return BLI_snprintf(str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc);
+ return BLI_snprintf_rlen(str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc);
}
/* XXX - hackish function needed for transforming strips! TODO - have some better solution */
@@ -4280,7 +4884,7 @@ static 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);
+ BKE_sound_cache(seq->sound);
}
seq_load->tot_success++;
@@ -4310,6 +4914,8 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine)
seq->pitch = 1.0f;
seq->scene_sound = NULL;
+ seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
+
return seq;
}
@@ -4367,6 +4973,12 @@ Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoad
strip->stripdata = MEM_callocN(seq->len * sizeof(StripElem), "stripelem");
BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir));
+ if (seq_load->stereo3d_format)
+ *seq->stereo3d_format = *seq_load->stereo3d_format;
+
+ seq->views_format = seq_load->views_format;
+ seq->flag |= seq_load->flag & SEQ_USE_VIEWS;
+
seq_load_apply(scene, seq, seq_load);
return seq;
@@ -4386,9 +4998,9 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
AUD_SoundInfo info;
- sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */
+ sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
- if (sound == NULL || sound->playback_handle == NULL) {
+ if (sound->playback_handle == NULL) {
#if 0
if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
@@ -4400,7 +5012,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
info = AUD_getInfo(sound->playback_handle);
if (info.specs.channels == AUD_CHANNELS_INVALID) {
- sound_delete(bmain, sound);
+ BKE_sound_delete(bmain, sound);
#if 0
if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
@@ -4425,7 +5037,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
- seq->scene_sound = sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + seq->len, 0);
+ seq->scene_sound = BKE_sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + seq->len, 0);
BKE_sequence_calc_disp(scene, seq);
@@ -4446,6 +5058,12 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
}
#endif // WITH_AUDASPACE
+static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const size_t view_id)
+{
+ const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id);
+ IMB_suffix_anim(anim, suffix);
+}
+
Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
{
Scene *scene = CTX_data_scene(C); /* only for sound */
@@ -4455,29 +5073,84 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
Strip *strip;
StripElem *se;
char colorspace[64] = "\0"; /* MAX_COLORSPACE_NAME */
-
- struct anim *an;
+ bool is_multiview_loaded = false;
+ const bool is_multiview = (seq_load->flag & SEQ_USE_VIEWS) != 0;
+ size_t totfiles = seq_num_files(scene, seq_load->views_format, is_multiview);
+ struct anim **anim_arr;
+ int i;
BLI_strncpy(path, seq_load->path, sizeof(path));
BLI_path_abs(path, G.main->name);
- an = openanim(path, IB_rect, 0, colorspace);
+ anim_arr = MEM_callocN(sizeof(struct anim *) * totfiles, "Video files");
- if (an == NULL)
- return NULL;
+ if (is_multiview && (seq_load->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
+ char prefix[FILE_MAX];
+ const char *ext = NULL;
+ size_t j = 0;
+
+ BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
+
+ if (prefix[0] != '\0') {
+ for (i = 0; i < totfiles; i++) {
+ char str[FILE_MAX];
+
+ seq_multiview_name(scene, i, prefix, ext, str, FILE_MAX);
+ anim_arr[j] = openanim(str, IB_rect, 0, colorspace);
+
+ if (anim_arr[j]) {
+ seq_anim_add_suffix(scene, anim_arr[j], i);
+ j++;
+ }
+ }
+
+ if (j == 0) {
+ MEM_freeN(anim_arr);
+ return NULL;
+ }
+ is_multiview_loaded = true;
+ }
+ }
+
+ if (is_multiview_loaded == false) {
+ anim_arr[0] = openanim(path, IB_rect, 0, colorspace);
+
+ if (anim_arr[0] == NULL) {
+ MEM_freeN(anim_arr);
+ return NULL;
+ }
+ }
seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel);
+
+ /* multiview settings */
+ if (seq_load->stereo3d_format) {
+ *seq->stereo3d_format = *seq_load->stereo3d_format;
+ seq->views_format = seq_load->views_format;
+ }
+ seq->flag |= seq_load->flag & SEQ_USE_VIEWS;
+
seq->type = SEQ_TYPE_MOVIE;
seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
- seq->anim = an;
- seq->anim_preseek = IMB_anim_get_preseek(an);
+ for (i = 0; i < totfiles; i++) {
+ if (anim_arr[i]) {
+ StripAnim *sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
+ sanim->anim = anim_arr[i];
+ }
+ else {
+ break;
+ }
+ }
+
+ seq->anim_preseek = IMB_anim_get_preseek(anim_arr[0]);
BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2);
BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
/* basic defaults */
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
- seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
+ seq->len = IMB_anim_get_duration(anim_arr[0], IMB_TC_RECORD_RUN);
strip->us = 1;
BLI_strncpy(seq->strip->colorspace_settings.name, colorspace, sizeof(seq->strip->colorspace_settings.name));
@@ -4505,6 +5178,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
/* can be NULL */
seq_load_apply(scene, seq, seq_load);
+ MEM_freeN(anim_arr);
return seq;
}
@@ -4516,6 +5190,8 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seq->tmp = seqn;
seqn->strip = MEM_dupallocN(seq->strip);
+ seqn->stereo3d_format = MEM_dupallocN(seq->stereo3d_format);
+
/* XXX: add F-Curve duplication stuff? */
if (seq->strip->crop) {
@@ -4531,6 +5207,10 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->proxy->anim = NULL;
}
+ if (seq->prop) {
+ seqn->prop = IDP_CopyProperty(seq->prop);
+ }
+
if (seqn->modifiers.first) {
BLI_listbase_clear(&seqn->modifiers);
@@ -4547,7 +5227,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
if (seq->scene_sound)
- seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(sce_audio, seqn);
}
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
/* avoid assert */
@@ -4558,13 +5238,13 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
else if (seq->type == SEQ_TYPE_MOVIE) {
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
- seqn->anim = NULL;
+ BLI_listbase_clear(&seqn->anims);
}
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
if (seq->scene_sound)
- seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_add_scene_sound_defaults(sce_audio, seqn);
id_us_plus((ID *)seqn->sound);
}
@@ -4572,17 +5252,11 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
}
- else if (seq->type >= SEQ_TYPE_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_TYPE_EFFECT) {
- struct SeqEffectHandle sh;
- sh = BKE_sequence_get_effect(seq);
- if (sh.copy)
- sh.copy(seq, seqn);
- }
+ else if (seq->type & SEQ_TYPE_EFFECT) {
+ struct SeqEffectHandle sh;
+ sh = BKE_sequence_get_effect(seq);
+ if (sh.copy)
+ sh.copy(seq, seqn);
seqn->strip->stripdata = NULL;
@@ -4601,9 +5275,34 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
return seqn;
}
+static void seq_new_fix_links_recursive(Sequence *seq)
+{
+ SequenceModifierData *smd;
+
+ if (seq->type & SEQ_TYPE_EFFECT) {
+ if (seq->seq1 && seq->seq1->tmp) seq->seq1 = seq->seq1->tmp;
+ if (seq->seq2 && seq->seq2->tmp) seq->seq2 = seq->seq2->tmp;
+ if (seq->seq3 && seq->seq3->tmp) seq->seq3 = seq->seq3->tmp;
+ }
+ else if (seq->type == SEQ_TYPE_META) {
+ Sequence *seqn;
+ for (seqn = seq->seqbase.first; seqn; seqn = seqn->next) {
+ seq_new_fix_links_recursive(seqn);
+ }
+ }
+
+ for (smd = seq->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence && smd->mask_sequence->tmp)
+ smd->mask_sequence = smd->mask_sequence->tmp;
+ }
+}
+
Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag)
{
- Sequence *seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ Sequence *seqn;
+
+ seq->tmp = NULL;
+ seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
if (seq->type == SEQ_TYPE_META) {
Sequence *s;
for (s = seq->seqbase.first; s; s = s->next) {
@@ -4613,14 +5312,21 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
}
}
}
+
+ seq_new_fix_links_recursive(seqn);
+
return seqn;
}
-void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag)
+void BKE_sequence_base_dupli_recursive(
+ Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
+ int dupe_flag)
{
Sequence *seq;
Sequence *seqn = NULL;
Sequence *last_seq = BKE_sequencer_active_get(scene);
+ /* always include meta's strips */
+ int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL;
for (seq = seqbase->first; seq; seq = seq->next) {
seq->tmp = NULL;
@@ -4633,8 +5339,11 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
}
BLI_addtail(nseqbase, seqn);
- if (seq->type == SEQ_TYPE_META)
- BKE_sequence_base_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag);
+ if (seq->type == SEQ_TYPE_META) {
+ BKE_sequence_base_dupli_recursive(
+ scene, scene_to, &seqn->seqbase, &seq->seqbase,
+ dupe_flag_recursive);
+ }
if (dupe_flag & SEQ_DUPE_CONTEXT) {
if (seq == last_seq) {
@@ -4644,6 +5353,11 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
}
}
}
+
+ /* fix modifier linking */
+ for (seq = nseqbase->first; seq; seq = seq->next) {
+ seq_new_fix_links_recursive(seq);
+ }
}
/* called on draw, needs to be fast,
@@ -4664,3 +5378,70 @@ bool BKE_sequence_is_valid_check(Sequence *seq)
return true;
}
+int BKE_sequencer_find_next_prev_edit(
+ Scene *scene, int cfra, const short side,
+ const bool do_skip_mute, const bool do_center, const bool do_unselected)
+{
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+
+ int dist, best_dist, best_frame = cfra;
+ int seq_frames[2], seq_frames_tot;
+
+ /* in case where both is passed, frame just finds the nearest end while frame_left the nearest start */
+
+ best_dist = MAXFRAME * 2;
+
+ if (ed == NULL) return cfra;
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ int i;
+
+ if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
+ continue;
+ }
+
+ if (do_unselected && (seq->flag & SELECT))
+ continue;
+
+ if (do_center) {
+ seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
+ seq_frames_tot = 1;
+ }
+ else {
+ seq_frames[0] = seq->startdisp;
+ seq_frames[1] = seq->enddisp;
+
+ seq_frames_tot = 2;
+ }
+
+ for (i = 0; i < seq_frames_tot; i++) {
+ const int seq_frame = seq_frames[i];
+
+ dist = MAXFRAME * 2;
+
+ switch (side) {
+ case SEQ_SIDE_LEFT:
+ if (seq_frame < cfra) {
+ dist = cfra - seq_frame;
+ }
+ break;
+ case SEQ_SIDE_RIGHT:
+ if (seq_frame > cfra) {
+ dist = seq_frame - cfra;
+ }
+ break;
+ case SEQ_SIDE_BOTH:
+ dist = abs(seq_frame - cfra);
+ break;
+ }
+
+ if (dist < best_dist) {
+ best_frame = seq_frame;
+ best_dist = dist;
+ }
+ }
+ }
+
+ return best_frame;
+}