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.c1074
1 files changed, 850 insertions, 224 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index c45db303467..4ec5dd58973 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -53,6 +53,12 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#else
+# include <unistd.h>
+#endif
+
#include "BLF_translation.h"
#include "BKE_animsys.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"
@@ -88,6 +95,8 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seq
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)
@@ -316,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;
@@ -531,6 +562,7 @@ void BKE_sequencer_new_render_data(
r_context->motion_blur_shutter = 0;
r_context->skip_cache = false;
r_context->is_proxy_render = false;
+ r_context->view_id = 0;
}
/* ************************* iterator ************************** */
@@ -652,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);
}
}
@@ -765,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 */
@@ -801,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);
- seq->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;
+ }
+ }
- if (!seq->anim) {
+ /* use the first video as reference for everything */
+ sanim = seq->anims.first;
+
+ 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;
@@ -824,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;
@@ -1076,30 +1161,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;
}
}
@@ -1181,7 +1261,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;
}
@@ -1291,6 +1371,7 @@ typedef struct SeqIndexBuildContext {
int size_flags;
int quality;
bool overwrite;
+ size_t view_id;
Main *bmain;
Scene *scene;
@@ -1330,54 +1411,164 @@ static double seq_rendersize_to_scale_factor(int size)
return 0.25;
}
-static void seq_open_anim_file(Sequence *seq, bool openfile)
+/* 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);
-
- if (openfile) {
- seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
- seq->streamindex, seq->strip->colorspace_settings.name);
- }
- else {
- seq->anim = openanim_noload(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;
}
@@ -1389,8 +1580,32 @@ 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);
@@ -1399,10 +1614,16 @@ static bool seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *
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;
}
@@ -1410,13 +1631,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);
@@ -1433,45 +1654,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;
}
- seq->strip->proxy->anim = openanim(name, IB_rect, 0,
- seq->strip->colorspace_settings.name);
+ 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, true);
+ 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;
}
@@ -1496,8 +1720,9 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
int rectx, recty;
int ok;
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;
}
@@ -1512,6 +1737,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
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);
}
@@ -1538,44 +1764,133 @@ 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, struct GSet *file_list)
+/* 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;
+
+ context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
+
+ nseq = BKE_sequence_dupli_recursive(scene, scene, seq, 0);
+
+ 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;
- 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;
+ context->view_id = i; /* only for images */
- context->bmain = bmain;
- context->scene = scene;
- context->orig_seq = seq;
- context->seq = nseq;
+ link = BLI_genericNodeN(context);
+ BLI_addtail(queue, link);
- if (nseq->type == SEQ_TYPE_MOVIE) {
- seq_open_anim_file(nseq, true);
+ if (nseq->type == SEQ_TYPE_MOVIE) {
+ StripAnim *sanim;
- if (nseq->anim) {
- context->index_context = IMB_anim_index_rebuild_context(nseq->anim,
- context->tc_flags, context->size_flags, context->quality,
- context->overwrite, file_list);
+ 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)
@@ -1600,7 +1915,7 @@ 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;
}
@@ -1614,6 +1929,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
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) {
@@ -1640,8 +1956,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);
}
@@ -2102,6 +2424,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;
@@ -2153,6 +2476,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;
}
@@ -2175,6 +2499,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);
}
@@ -2188,9 +2513,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);
}
@@ -2386,6 +2713,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;
@@ -2517,7 +3075,7 @@ 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;
@@ -2615,6 +3173,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
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 */
@@ -2626,14 +3185,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,
- use_gpencil, 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
*
@@ -2653,27 +3216,51 @@ 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();
}
@@ -2700,7 +3287,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:
@@ -2759,64 +3345,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, false);
-
- if (seq->anim) {
- IMB_Proxy_Size proxy_size = seq_rendersize_to_proxysize(context->preview_render_size);
- 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,
- proxy_size);
-
- /* fetching for requested proxy size failed, try fetching the original instead */
- if (!ibuf && proxy_size != IMB_PROXY_NONE) {
- ibuf = IMB_anim_absolute(seq->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;
- }
- }
+ ibuf = seq_render_movie_strip(context, seq, nr, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
@@ -2824,7 +3360,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);
@@ -3053,6 +3589,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);
}
@@ -3321,16 +3859,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)
{
@@ -3382,15 +3910,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);
}
@@ -3437,7 +3961,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);
@@ -3484,7 +4008,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);
}
@@ -3736,10 +4260,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);
}
}
}
@@ -3951,11 +4475,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 */
}
@@ -3980,7 +4504,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);
}
}
}
@@ -4009,7 +4533,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);
}
}
}
@@ -4124,7 +4648,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 */
@@ -4342,7 +4866,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++;
@@ -4372,6 +4896,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;
}
@@ -4429,6 +4955,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;
@@ -4448,9 +4980,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");
@@ -4462,7 +4994,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");
@@ -4487,7 +5019,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);
@@ -4508,6 +5040,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 */
@@ -4517,29 +5055,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));
@@ -4567,6 +5160,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;
}
@@ -4578,6 +5172,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) {
@@ -4593,6 +5189,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);
@@ -4609,7 +5209,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 */
@@ -4620,13 +5220,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);
}
@@ -4635,10 +5235,6 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
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);
@@ -4663,6 +5259,28 @@ 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);
@@ -4675,6 +5293,9 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
}
}
}
+
+ seq_new_fix_links_recursive(seqn);
+
return seqn;
}
@@ -4713,6 +5334,11 @@ void BKE_sequence_base_dupli_recursive(
}
}
}
+
+ /* fix modifier linking */
+ for (seq = nseqbase->first; seq; seq = seq->next) {
+ seq_new_fix_links_recursive(seq);
+ }
}
/* called on draw, needs to be fast,