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:
authorDalai Felinto <dfelinto@gmail.com>2015-04-06 16:40:12 +0300
committerDalai Felinto <dfelinto@gmail.com>2015-04-06 16:40:12 +0300
commitd5f1b9c2223333e03f2e4994171ad9df8c1c4f21 (patch)
treebe6b81d2c439249af96b8b28b5013dcbb735b937 /source/blender/blenkernel/intern/sequencer.c
parent74df307ca43df14b759fd9eb6a049a6c5d90dcda (diff)
Multi-View and Stereo 3D
Official Documentation: http://www.blender.org/manual/render/workflows/multiview.html Implemented Features ==================== Builtin Stereo Camera * Convergence Mode * Interocular Distance * Convergence Distance * Pivot Mode Viewport * Cameras * Plane * Volume Compositor * View Switch Node * Image Node Multi-View OpenEXR support Sequencer * Image/Movie Strips 'Use Multiview' UV/Image Editor * Option to see Multi-View images in Stereo-3D or its individual images * Save/Open Multi-View (OpenEXR, Stereo3D, individual views) images I/O * Save/Open Multi-View (OpenEXR, Stereo3D, individual views) images Scene Render Views * Ability to have an arbitrary number of views in the scene Missing Bits ============ First rule of Multi-View bug report: If something is not working as it should *when Views is off* this is a severe bug, do mention this in the report. Second rule is, if something works *when Views is off* but doesn't (or crashes) when *Views is on*, this is a important bug. Do mention this in the report. Everything else is likely small todos, and may wait until we are sure none of the above is happening. Apart from that there are those known issues: * Compositor Image Node poorly working for Multi-View OpenEXR (this was working prefectly before the 'Use Multi-View' functionality) * Selecting camera from Multi-View when looking from camera is problematic * Animation Playback (ctrl+F11) doesn't support stereo formats * Wrong filepath when trying to play back animated scene * Viewport Rendering doesn't support Multi-View * Overscan Rendering * Fullscreen display modes need to warn the user * Object copy should be aware of views suffix Acknowledgments =============== * Francesco Siddi for the help with the original feature specs and design * Brecht Van Lommel for the original review of the code and design early on * Blender Foundation for the Development Fund to support the project wrap up Final patch reviewers: * Antony Riakiotakis (psy-fi) * Campbell Barton (ideasman42) * Julian Eisel (Severin) * Sergey Sharybin (nazgul) * Thomas Dinged (dingto) Code contributors of the original branch in github: * Alexey Akishin * Gabriel Caraballo
Diffstat (limited to 'source/blender/blenkernel/intern/sequencer.c')
-rw-r--r--source/blender/blenkernel/intern/sequencer.c902
1 files changed, 717 insertions, 185 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 721555097d7..942426febdd 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"
@@ -89,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
@@ -181,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);
@@ -196,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
*/
@@ -240,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;
+ BLI_remlink(&seq->anims, sanim);
+
+ if (sanim->anim) {
+ IMB_free_anim(sanim->anim);
+ sanim->anim = NULL;
+ }
+
+ MEM_freeN(sanim);
+ }
+}
+
/* 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)
@@ -537,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 ************************** */
@@ -771,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 */
@@ -807,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];
+ 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 (seq->anim) IMB_free_anim(seq->anim);
+ if (prefix[0] != '\0') {
+ for (i = 0; i < totfiles; i++) {
+ struct anim *anim;
+ char str[FILE_MAX];
- seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
- seq->streamindex, seq->strip->colorspace_settings.name);
+ 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_add_suffix(scene, anim, i);
- if (!seq->anim) {
+ if (anim) {
+ 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;
+ }
+ }
+
+ /* 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;
@@ -830,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;
@@ -1297,6 +1376,7 @@ typedef struct SeqIndexBuildContext {
int size_flags;
int quality;
bool overwrite;
+ size_t view_id;
Main *bmain;
Scene *scene;
@@ -1336,44 +1416,59 @@ static double seq_rendersize_to_scale_factor(int size)
return 0.25;
}
-static void seq_open_anim_file(Editing *ed, 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;
- if (proxy == NULL) {
- return;
- }
-
- if ((proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) ||
- (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE))
- {
- char dir[FILE_MAX];
- char fname[FILE_MAXFILE];
+ 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));
@@ -1383,21 +1478,93 @@ static void seq_open_anim_file(Editing *ed, Sequence *seq, bool openfile)
else {
BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
}
+ BLI_path_abs(dir, G.main->name);
+ }
- IMB_anim_get_fname(seq->anim, fname, FILE_MAXFILE);
- BLI_path_append(dir, sizeof(dir), fname);
+ 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];
+ char *ext = NULL;
+ int i;
- BLI_path_abs(dir, G.main->name);
+ 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");
- IMB_anim_set_index_dir(seq->anim, dir);
+ 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);
+ }
+
+ seq_anim_add_suffix(scene, sanim->anim, i);
+
+ if (sanim->anim == NULL) {
+ 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 (is_multiview_loaded == false) {
+ StripAnim *sanim;
+
+ sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
-static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render_size, char *name)
+ 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(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'};
StripProxy *proxy = seq->strip->proxy;
if (!proxy) {
@@ -1412,23 +1579,25 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
* have both, a directory full of jpeg files and proxy avis, so
* sorry folks, please rebuild your proxies... */
- if (seq->anim && ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
+ sanim = BLI_findlink(&seq->anims, view_id);
+
+ if (sanim && sanim->anim && 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));
- IMB_anim_get_fname(seq->anim, fname, FILE_MAXFILE);
+ IMB_anim_get_fname(sanim->anim, fname, FILE_MAXFILE);
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 (seq->anim && (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_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(seq->anim, fname, FILE_MAXFILE);
+ IMB_anim_get_fname(sanim->anim, fname, FILE_MAXFILE);
BLI_path_append(dir, sizeof(dir), fname);
}
else if (seq->type == SEQ_TYPE_IMAGE) {
@@ -1438,12 +1607,16 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
return false;
}
- if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE && seq->anim &&
+ 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, proxy->file);
BLI_path_abs(name, G.main->name);
+ BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", name, suffix);
return true;
}
@@ -1451,13 +1624,13 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
/* 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);
@@ -1476,6 +1649,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
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;
@@ -1496,7 +1670,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
int frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs;
if (proxy->anim == NULL) {
- if (seq_proxy_get_fname(ed, seq, cfra, render_size, name) == 0) {
+ if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) {
return NULL;
}
@@ -1506,14 +1680,15 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
return NULL;
}
- seq_open_anim_file(context->scene->ed, seq, true);
+ seq_open_anim_file(context->scene, seq, true);
+ sanim = seq->anims.first;
- frameno = IMB_anim_index_get_frame_index(seq->anim, proxy->tc, frameno);
+ frameno = IMB_anim_index_get_frame_index(sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno);
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
- if (seq_proxy_get_fname(ed, seq, cfra, render_size, name) == 0) {
+ if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) {
return NULL;
}
@@ -1540,7 +1715,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
ImBuf *ibuf_tmp, *ibuf;
Editing *ed = context->scene->ed;
- if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name)) {
+ if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) {
return;
}
@@ -1581,44 +1756,130 @@ 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 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);
+ }
+
+ 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);
- 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;
- 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->bmain = bmain;
+ context->scene = scene;
+ context->orig_seq = seq;
+ context->seq = nseq;
- context->bmain = bmain;
- context->scene = scene;
- context->orig_seq = seq;
- context->seq = nseq;
+ context->view_id = i; /* only for images */
- if (nseq->type == SEQ_TYPE_MOVIE) {
- seq_open_anim_file(scene->ed, nseq, true);
+ link = BLI_genericNodeN(context);
+ BLI_addtail(queue, link);
- 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);
+ 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)
@@ -1657,6 +1918,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) {
@@ -1683,8 +1945,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);
}
@@ -2429,6 +2697,234 @@ 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;
+ 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];
+ 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;
+ }
+ }
+
+ 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;
@@ -2560,7 +3056,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;
@@ -2658,6 +3154,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 */
@@ -2669,14 +3166,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
*
@@ -2696,27 +3197,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();
}
@@ -2743,7 +3268,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:
@@ -2802,64 +3326,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(context->scene->ed, 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;
}
@@ -2867,7 +3341,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);
@@ -3364,16 +3838,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)
{
@@ -3425,15 +3889,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);
}
@@ -3480,7 +3940,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);
@@ -3527,7 +3987,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);
}
@@ -4415,6 +4875,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;
}
@@ -4472,6 +4934,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;
@@ -4551,6 +5019,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 */
@@ -4560,29 +5034,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];
+ 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);
+ seq_anim_add_suffix(scene, anim_arr[j], i);
+
+ if (anim_arr[j]) {
+ 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));
@@ -4610,6 +5139,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;
}
@@ -4621,6 +5151,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) {
@@ -4667,7 +5199,7 @@ 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 =