Cleanup and remove SEQ_ALL_BEGIN macro

We now use a for_each function with callback to iterate through all sequences in the scene.

This has the benefit that we now only loop over the sequences in the scene once.
Before we would loop over them twice and allocate memory to store temporary data.

The allocation of temporary data lead to unintentional memory leaks if the code used returns to exit out of the iteration loop.
The new for_each callback method doesn't allocate any temporary data and only iterates though all sequences once.

Reviewed By: Richard Antalik, Bastien Montagne

Differential Revision: http://developer.blender.org/D12278
This commit is contained in:
Sebastian Parborg 2021-08-20 16:30:34 +02:00
parent 796035ad93
commit f49d438ced
Notes: blender-bot 2023-02-14 04:24:05 +01:00
Referenced by commit 6c11733dfb, Fix T91190: Remove gaps operator not working
Referenced by issue #91190, VSE: Out-of-bounds metastrip contents block operation of "Remove Gaps" function on main timeline
28 changed files with 918 additions and 738 deletions

View File

@ -264,14 +264,6 @@ void BKE_scene_cursor_from_mat4(struct View3DCursor *cursor,
const float mat[4][4],
bool use_compat);
/* Dependency graph evaluation. */
/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation.
* This does NOT include actual rendering of the strips, but rather makes them up-to-date for
* animation playback and makes them ready for the sequencer's rendering pipeline to render them.
*/
void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scene *scene);
#ifdef __cplusplus
}
#endif

View File

@ -534,6 +534,46 @@ static bool rewrite_path_alloc(char **path,
return false;
}
typedef struct Seq_callback_data {
const char *absbase;
void *bpath_user_data;
BPathVisitor visit_cb;
const int flag;
} Seq_callback_data;
static bool seq_rewrite_path_callback(Sequence *seq, void *user_data)
{
if (SEQ_HAS_PATH(seq)) {
StripElem *se = seq->strip->stripdata;
Seq_callback_data *cd = (Seq_callback_data *)user_data;
if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) {
rewrite_path_fixed_dirfile(
seq->strip->dir, se->name, cd->visit_cb, cd->absbase, cd->bpath_user_data);
}
else if ((seq->type == SEQ_TYPE_IMAGE) && se) {
/* might want an option not to loop over all strips */
unsigned int len = (unsigned int)MEM_allocN_len(se) / (unsigned int)sizeof(*se);
unsigned int i;
if (cd->flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) {
/* only operate on one path */
len = MIN2(1u, len);
}
for (i = 0; i < len; i++, se++) {
rewrite_path_fixed_dirfile(
seq->strip->dir, se->name, cd->visit_cb, cd->absbase, cd->bpath_user_data);
}
}
else {
/* simple case */
rewrite_path_fixed(seq->strip->dir, cd->visit_cb, cd->absbase, cd->bpath_user_data);
}
}
return true;
}
/**
* Run visitor function 'visit' on all paths contained in 'id'.
*/
@ -701,38 +741,8 @@ void BKE_bpath_traverse_id(
case ID_SCE: {
Scene *scene = (Scene *)id;
if (scene->ed) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (SEQ_HAS_PATH(seq)) {
StripElem *se = seq->strip->stripdata;
if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM) && se) {
rewrite_path_fixed_dirfile(
seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
}
else if ((seq->type == SEQ_TYPE_IMAGE) && se) {
/* might want an option not to loop over all strips */
unsigned int len = (unsigned int)MEM_allocN_len(se) / (unsigned int)sizeof(*se);
unsigned int i;
if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) {
/* only operate on one path */
len = MIN2(1u, len);
}
for (i = 0; i < len; i++, se++) {
rewrite_path_fixed_dirfile(
seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
}
}
else {
/* simple case */
rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data);
}
}
}
SEQ_ALL_END;
Seq_callback_data user_data = {absbase, bpath_user_data, visit_cb, flag};
SEQ_for_each_callback(&scene->ed->seqbase, seq_rewrite_path_callback, &user_data);
}
break;
}

View File

@ -2038,6 +2038,58 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips)
}
}
typedef struct Seq_callback_data {
Main *bmain;
Scene *scene;
AnimData *adt;
} Seq_callback_data;
static bool seq_convert_callback(Sequence *seq, void *userdata)
{
IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL;
short adrcode = SEQ_FAC1;
if (G.debug & G_DEBUG) {
printf("\tconverting sequence strip %s\n", seq->name + 2);
}
if (ELEM(NULL, seq->ipo, icu)) {
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
return true;
}
/* patch adrcode, so that we can map
* to different DNA variables later
* (semi-hack (tm) )
*/
switch (seq->type) {
case SEQ_TYPE_IMAGE:
case SEQ_TYPE_META:
case SEQ_TYPE_SCENE:
case SEQ_TYPE_MOVIE:
case SEQ_TYPE_COLOR:
adrcode = SEQ_FAC_OPACITY;
break;
case SEQ_TYPE_SPEED:
adrcode = SEQ_FAC_SPEED;
break;
}
icu->adrcode = adrcode;
Seq_callback_data *cd = (Seq_callback_data *)userdata;
/* convert IPO */
ipo_to_animdata(cd->bmain, (ID *)cd->scene, seq->ipo, NULL, NULL, seq);
if (cd->adt->action) {
cd->adt->action->idroot = ID_SCE; /* scene-rooted */
}
id_us_min(&seq->ipo->id);
seq->ipo = NULL;
return true;
}
/* *************************************************** */
/* External API - Only Called from do_versions() */
@ -2286,52 +2338,8 @@ void do_versions_ipos_to_animato(Main *bmain)
Scene *scene = (Scene *)id;
Editing *ed = scene->ed;
if (ed && ed->seqbasep) {
Sequence *seq;
AnimData *adt = BKE_animdata_ensure_id(id);
SEQ_ALL_BEGIN (ed, seq) {
IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL;
short adrcode = SEQ_FAC1;
if (G.debug & G_DEBUG) {
printf("\tconverting sequence strip %s\n", seq->name + 2);
}
if (ELEM(NULL, seq->ipo, icu)) {
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
continue;
}
/* patch adrcode, so that we can map
* to different DNA variables later
* (semi-hack (tm) )
*/
switch (seq->type) {
case SEQ_TYPE_IMAGE:
case SEQ_TYPE_META:
case SEQ_TYPE_SCENE:
case SEQ_TYPE_MOVIE:
case SEQ_TYPE_COLOR:
adrcode = SEQ_FAC_OPACITY;
break;
case SEQ_TYPE_SPEED:
adrcode = SEQ_FAC_SPEED;
break;
}
icu->adrcode = adrcode;
/* convert IPO */
ipo_to_animdata(bmain, (ID *)scene, seq->ipo, NULL, NULL, seq);
if (adt->action) {
adt->action->idroot = ID_SCE; /* scene-rooted */
}
id_us_min(&seq->ipo->id);
seq->ipo = NULL;
}
SEQ_ALL_END;
Seq_callback_data cb_data = {bmain, scene, BKE_animdata_ensure_id(id)};
SEQ_for_each_callback(&ed->seqbase, seq_convert_callback, &cb_data);
}
}

View File

@ -113,11 +113,7 @@
#include "SEQ_edit.h"
#include "SEQ_iterator.h"
#include "SEQ_modifier.h"
#include "SEQ_proxy.h"
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
#include "SEQ_sound.h"
#include "BLO_read_write.h"
@ -702,6 +698,40 @@ static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase
}
}
static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
#define FOREACHID_PROCESS(_data, _id_super, _cb_flag) \
{ \
CHECK_TYPE(&((_id_super)->id), ID *); \
if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
return false; \
} \
} \
((void)0)
FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF);
FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP);
FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER);
FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER);
FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER);
IDP_foreach_property(
seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER);
}
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
TextVars *text_data = seq->effectdata;
FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER);
}
#undef FOREACHID_PROCESS
return true;
}
static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
{
Scene *scene = (Scene *)id;
@ -717,25 +747,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree);
}
if (scene->ed) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
BKE_LIB_FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF);
BKE_LIB_FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER);
BKE_LIB_FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER);
BKE_LIB_FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER);
IDP_foreach_property(
seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
BKE_LIB_FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER);
}
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
TextVars *text_data = seq->effectdata;
BKE_LIB_FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER);
}
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_member_id_cb, data);
}
/* This pointer can be NULL during old files reading, better be safe than sorry. */
@ -883,87 +895,9 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
Editing *ed = sce->ed;
if (ed) {
Sequence *seq;
BLO_write_struct(writer, Editing, ed);
/* reset write flags too */
SEQ_ALL_BEGIN (ed, seq) {
if (seq->strip) {
seq->strip->done = false;
}
BLO_write_struct(writer, Sequence, seq);
}
SEQ_ALL_END;
SEQ_ALL_BEGIN (ed, seq) {
if (seq->strip && seq->strip->done == 0) {
/* write strip with 'done' at 0 because readfile */
if (seq->effectdata) {
switch (seq->type) {
case SEQ_TYPE_COLOR:
BLO_write_struct(writer, SolidColorVars, seq->effectdata);
break;
case SEQ_TYPE_SPEED:
BLO_write_struct(writer, SpeedControlVars, seq->effectdata);
break;
case SEQ_TYPE_WIPE:
BLO_write_struct(writer, WipeVars, seq->effectdata);
break;
case SEQ_TYPE_GLOW:
BLO_write_struct(writer, GlowVars, seq->effectdata);
break;
case SEQ_TYPE_TRANSFORM:
BLO_write_struct(writer, TransformVars, seq->effectdata);
break;
case SEQ_TYPE_GAUSSIAN_BLUR:
BLO_write_struct(writer, GaussianBlurVars, seq->effectdata);
break;
case SEQ_TYPE_TEXT:
BLO_write_struct(writer, TextVars, seq->effectdata);
break;
case SEQ_TYPE_COLORMIX:
BLO_write_struct(writer, ColorMixVars, seq->effectdata);
break;
}
}
BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format);
Strip *strip = seq->strip;
BLO_write_struct(writer, Strip, strip);
if (strip->crop) {
BLO_write_struct(writer, StripCrop, strip->crop);
}
if (strip->transform) {
BLO_write_struct(writer, StripTransform, strip->transform);
}
if (strip->proxy) {
BLO_write_struct(writer, StripProxy, strip->proxy);
}
if (seq->type == SEQ_TYPE_IMAGE) {
BLO_write_struct_array(writer,
StripElem,
MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem),
strip->stripdata);
}
else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
BLO_write_struct(writer, StripElem, strip->stripdata);
}
strip->done = true;
}
if (seq->prop) {
IDP_BlendWrite(writer, seq->prop);
}
SEQ_modifier_blend_write(writer, &seq->modifiers);
}
SEQ_ALL_END;
SEQ_blend_write(writer, &ed->seqbase);
/* new; meta stack too, even when its nasty restore code */
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
BLO_write_struct(writer, MetaStack, ms);
@ -1155,66 +1089,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
/* recursive link sequences, lb will be correctly initialized */
link_recurs_seq(reader, &ed->seqbase);
Sequence *seq;
SEQ_ALL_BEGIN (ed, seq) {
/* Do as early as possible, so that other parts of reading can rely on valid session UUID. */
SEQ_relations_session_uuid_generate(seq);
BLO_read_data_address(reader, &seq->seq1);
BLO_read_data_address(reader, &seq->seq2);
BLO_read_data_address(reader, &seq->seq3);
/* a patch: after introduction of effects with 3 input strips */
if (seq->seq3 == NULL) {
seq->seq3 = seq->seq2;
}
BLO_read_data_address(reader, &seq->effectdata);
BLO_read_data_address(reader, &seq->stereo3d_format);
if (seq->type & SEQ_TYPE_EFFECT) {
seq->flag |= SEQ_EFFECT_NOT_LOADED;
}
if (seq->type == SEQ_TYPE_TEXT) {
TextVars *t = seq->effectdata;
t->text_blf_id = SEQ_FONT_NOT_LOADED;
}
BLO_read_data_address(reader, &seq->prop);
IDP_BlendDataRead(reader, &seq->prop);
BLO_read_data_address(reader, &seq->strip);
if (seq->strip && seq->strip->done == 0) {
seq->strip->done = true;
if (ELEM(seq->type,
SEQ_TYPE_IMAGE,
SEQ_TYPE_MOVIE,
SEQ_TYPE_SOUND_RAM,
SEQ_TYPE_SOUND_HD)) {
BLO_read_data_address(reader, &seq->strip->stripdata);
}
else {
seq->strip->stripdata = NULL;
}
BLO_read_data_address(reader, &seq->strip->crop);
BLO_read_data_address(reader, &seq->strip->transform);
BLO_read_data_address(reader, &seq->strip->proxy);
if (seq->strip->proxy) {
seq->strip->proxy->anim = NULL;
}
else if (seq->flag & SEQ_USE_PROXY) {
SEQ_proxy_set(seq, true);
}
/* need to load color balance to it could be converted to modifier */
BLO_read_data_address(reader, &seq->strip->color_balance);
}
SEQ_modifier_blend_read_data(reader, &seq->modifiers);
}
SEQ_ALL_END;
/* Read in sequence member data. */
SEQ_blend_read(reader, &ed->seqbase);
/* link metastack, slight abuse of structs here,
* have to restore pointer to internal part in struct */
@ -1461,50 +1337,9 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
}
}
Sequence *seq;
SEQ_ALL_BEGIN (sce->ed, seq) {
IDP_BlendReadLib(reader, seq->prop);
if (seq->ipo) {
/* XXX: deprecated - old animation system. */
BLO_read_id_address(reader, sce->id.lib, &seq->ipo);
}
seq->scene_sound = NULL;
if (seq->scene) {
BLO_read_id_address(reader, sce->id.lib, &seq->scene);
seq->scene_sound = NULL;
}
if (seq->clip) {
BLO_read_id_address(reader, sce->id.lib, &seq->clip);
}
if (seq->mask) {
BLO_read_id_address(reader, sce->id.lib, &seq->mask);
}
if (seq->scene_camera) {
BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera);
}
if (seq->sound) {
seq->scene_sound = NULL;
if (seq->type == SEQ_TYPE_SOUND_HD) {
seq->type = SEQ_TYPE_SOUND_RAM;
}
else {
BLO_read_id_address(reader, sce->id.lib, &seq->sound);
}
if (seq->sound) {
id_us_plus_no_lib((ID *)seq->sound);
seq->scene_sound = NULL;
}
}
if (seq->type == SEQ_TYPE_TEXT) {
TextVars *t = seq->effectdata;
BLO_read_id_address(reader, sce->id.lib, &t->text_font);
}
BLI_listbase_clear(&seq->anims);
SEQ_modifier_blend_read_lib(reader, sce, &seq->modifiers);
if (sce->ed) {
SEQ_blend_read_lib(reader, sce, &sce->ed->seqbase);
}
SEQ_ALL_END;
LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
IDP_BlendReadLib(reader, marker->prop);
@ -1619,33 +1454,7 @@ static void scene_blend_read_expand(BlendExpander *expander, ID *id)
}
if (sce->ed) {
Sequence *seq;
SEQ_ALL_BEGIN (sce->ed, seq) {
IDP_BlendReadExpand(expander, seq->prop);
if (seq->scene) {
BLO_expand(expander, seq->scene);
}
if (seq->scene_camera) {
BLO_expand(expander, seq->scene_camera);
}
if (seq->clip) {
BLO_expand(expander, seq->clip);
}
if (seq->mask) {
BLO_expand(expander, seq->mask);
}
if (seq->sound) {
BLO_expand(expander, seq->sound);
}
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
TextVars *data = seq->effectdata;
BLO_expand(expander, data->text_font);
}
}
SEQ_ALL_END;
SEQ_blend_read_expand(expander, &sce->ed->seqbase);
}
if (sce->rigidbody_world) {
@ -3781,69 +3590,3 @@ void BKE_scene_cursor_from_mat4(View3DCursor *cursor, const float mat[4][4], boo
}
/** \} */
/* Dependency graph evaluation. */
static void scene_sequencer_disable_sound_strips(Scene *scene)
{
if (scene->sound_scene == NULL) {
return;
}
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->scene_sound != NULL) {
BKE_sound_remove_scene_sound(scene, seq->scene_sound);
seq->scene_sound = NULL;
}
}
SEQ_ALL_END;
}
void BKE_scene_eval_sequencer_sequences(Depsgraph *depsgraph, Scene *scene)
{
DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
if (scene->ed == NULL) {
return;
}
BKE_sound_ensure_scene(scene);
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->scene_sound == NULL) {
if (seq->sound != NULL) {
seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
}
else if (seq->type == SEQ_TYPE_SCENE) {
if (seq->scene != NULL) {
BKE_sound_ensure_scene(seq->scene);
seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq);
}
}
}
if (seq->scene_sound != NULL) {
/* Make sure changing volume via sequence's properties panel works correct.
*
* Ideally, the entire BKE_scene_update_sound() will happen from a dependency graph, so
* then it is no longer needed to do such manual forced updates. */
if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) {
BKE_sound_set_scene_volume(seq->scene, seq->scene->audio.volume);
if ((seq->flag & SEQ_SCENE_STRIPS) == 0) {
scene_sequencer_disable_sound_strips(seq->scene);
}
}
if (seq->sound != NULL) {
if (scene->id.recalc & ID_RECALC_AUDIO || seq->sound->id.recalc & ID_RECALC_AUDIO) {
BKE_sound_update_scene_sound(seq->scene_sound, seq->sound);
}
}
BKE_sound_set_scene_sound_volume(
seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);
BKE_sound_set_scene_sound_pitch(
seq->scene_sound, seq->pitch, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
BKE_sound_set_scene_sound_pan(
seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0);
}
}
SEQ_ALL_END;
SEQ_edit_update_muting(scene->ed);
SEQ_sound_update_bounds_all(scene);
}

View File

@ -2419,7 +2419,7 @@ static void lib_link_seq_clipboard_pt_restore(ID *id, struct IDNameLib_Map *id_m
id->newid = restore_pointer_by_name(id_map, id->newid, USER_REAL);
}
}
static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
{
struct IDNameLib_Map *id_map = arg_pt;
@ -2428,13 +2428,13 @@ static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
lib_link_seq_clipboard_pt_restore((ID *)seq->clip, id_map);
lib_link_seq_clipboard_pt_restore((ID *)seq->mask, id_map);
lib_link_seq_clipboard_pt_restore((ID *)seq->sound, id_map);
return 1;
return true;
}
static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map)
{
/* update IDs stored in sequencer clipboard */
SEQ_seqbase_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
SEQ_for_each_callback(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
}
static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)

View File

@ -638,6 +638,46 @@ static void do_versions_socket_default_value_259(bNodeSocket *sock)
}
}
static bool seq_sound_proxy_update_cb(Sequence *seq, void *user_data)
{
Main *bmain = (Main *)user_data;
if (seq->type == SEQ_TYPE_SOUND_HD) {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
seq->sound = BKE_sound_new_file(bmain, str);
}
#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
/* don't know, if anybody used that this way, but just in case, upgrade to new way... */
if ((seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) && !(seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) {
BLI_snprintf(seq->strip->proxy->dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir);
}
#undef SEQ_USE_PROXY_CUSTOM_DIR
#undef SEQ_USE_PROXY_CUSTOM_FILE
return true;
}
static bool seq_set_volume_cb(Sequence *seq, void *UNUSED(user_data))
{
seq->volume = 1.0f;
return true;
}
static bool seq_set_sat_cb(Sequence *seq, void *UNUSED(user_data))
{
if (seq->sat == 0.0f) {
seq->sat = 1.0f;
}
return true;
}
static bool seq_set_pitch_cb(Sequence *seq, void *UNUSED(user_data))
{
seq->pitch = 1.0f;
return true;
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
{
@ -660,7 +700,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
#endif
bSound *sound;
Sequence *seq;
for (sound = bmain->sounds.first; sound; sound = sound->id.next) {
if (sound->newpackedfile) {
@ -671,23 +710,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
if (scene->ed && scene->ed->seqbasep) {
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->type == SEQ_TYPE_SOUND_HD) {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
seq->sound = BKE_sound_new_file(bmain, str);
}
#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
/* don't know, if anybody used that this way, but just in case, upgrade to new way... */
if ((seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) && !(seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) {
BLI_snprintf(seq->strip->proxy->dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir);
}
#undef SEQ_USE_PROXY_CUSTOM_DIR
#undef SEQ_USE_PROXY_CUSTOM_FILE
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_sound_proxy_update_cb, bmain);
}
}
@ -1391,7 +1414,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 250, 17)) {
Scene *sce;
Sequence *seq;
/* initialize to sane default so toggling on border shows something */
for (sce = bmain->scenes.first; sce; sce = sce->id.next) {
@ -1406,11 +1428,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if ((sce->r.ffcodecdata.flags & FFMPEG_MULTIPLEX_AUDIO) == 0) {
sce->r.ffcodecdata.audio_codec = 0x0; /* `CODEC_ID_NONE` */
}
SEQ_ALL_BEGIN (sce->ed, seq) {
seq->volume = 1.0f;
if (sce->ed) {
SEQ_for_each_callback(&sce->ed->seqbase, seq_set_volume_cb, NULL);
}
SEQ_ALL_END;
}
/* particle brush strength factor was changed from int to float */
@ -1678,13 +1698,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
}
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->sat == 0.0f) {
seq->sat = 1.0f;
}
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_set_sat_cb, NULL);
}
SEQ_ALL_END;
}
/* GSOC 2010 Sculpt - New settings for Brush */
@ -2159,15 +2175,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 259, 1)) {
{
Scene *scene;
Sequence *seq;
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
scene->r.ffcodecdata.audio_channels = 2;
scene->audio.volume = 1.0f;
SEQ_ALL_BEGIN (scene->ed, seq) {
seq->pitch = 1.0f;
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_set_pitch_cb, NULL);
}
SEQ_ALL_END;
}
}

View File

@ -663,6 +663,53 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro
}
}
static bool seq_colorbalance_update_cb(Sequence *seq, void *UNUSED(user_data))
{
Strip *strip = seq->strip;
if (strip && strip->color_balance) {
SequenceModifierData *smd;
ColorBalanceModifierData *cbmd;
smd = SEQ_modifier_new(seq, NULL, seqModifierType_ColorBalance);
cbmd = (ColorBalanceModifierData *)smd;
cbmd->color_balance = *strip->color_balance;
/* multiplication with color balance used is handled differently,
* so we need to move multiplication to modifier so files would be
* compatible
*/
cbmd->color_multiply = seq->mul;
seq->mul = 1.0f;
MEM_freeN(strip->color_balance);
strip->color_balance = NULL;
}
return true;
}
static bool seq_set_alpha_mode_cb(Sequence *seq, void *UNUSED(user_data))
{
enum { SEQ_MAKE_PREMUL = (1 << 6) };
if (seq->flag & SEQ_MAKE_PREMUL) {
seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
else {
SEQ_alpha_mode_from_file_extension(seq);
}
return true;
}
static bool seq_set_wipe_angle_cb(Sequence *seq, void *UNUSED(user_data))
{
if (seq->type == SEQ_TYPE_WIPE) {
WipeVars *wv = seq->effectdata;
wv->angle = DEG2RADF(wv->angle);
}
return true;
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@ -1492,32 +1539,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
if (scene->ed) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
Strip *strip = seq->strip;
if (strip && strip->color_balance) {
SequenceModifierData *smd;
ColorBalanceModifierData *cbmd;
smd = SEQ_modifier_new(seq, NULL, seqModifierType_ColorBalance);
cbmd = (ColorBalanceModifierData *)smd;
cbmd->color_balance = *strip->color_balance;
/* multiplication with color balance used is handled differently,
* so we need to move multiplication to modifier so files would be
* compatible
*/
cbmd->color_multiply = seq->mul;
seq->mul = 1.0f;
MEM_freeN(strip->color_balance);
strip->color_balance = NULL;
}
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_colorbalance_update_cb, NULL);
}
}
}
@ -1807,18 +1829,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
Tex *tex;
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
enum { SEQ_MAKE_PREMUL = (1 << 6) };
if (seq->flag & SEQ_MAKE_PREMUL) {
seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
else {
SEQ_alpha_mode_from_file_extension(seq);
}
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_set_alpha_mode_cb, NULL);
}
SEQ_ALL_END;
if (scene->r.bake_samples == 0) {
scene->r.bake_samples = 256;
@ -2450,14 +2463,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->type == SEQ_TYPE_WIPE) {
WipeVars *wv = seq->effectdata;
wv->angle = DEG2RADF(wv->angle);
}
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_set_wipe_angle_cb, NULL);
}
SEQ_ALL_END;
}
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {

View File

@ -425,6 +425,45 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id),
}
}
static bool seq_update_proxy_cb(Sequence *seq, void *UNUSED(user_data))
{
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
if (seq->strip && seq->strip->proxy && !seq->strip->proxy->storage) {
if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_DIR;
}
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_FILE;
}
}
#undef SEQ_USE_PROXY_CUSTOM_DIR
#undef SEQ_USE_PROXY_CUSTOM_FILE
return true;
}
static bool seq_update_effectdata_cb(Sequence *seq, void *UNUSED(user_data))
{
if (seq->type != SEQ_TYPE_TEXT) {
return true;
}
if (seq->effectdata == NULL) {
struct SeqEffectHandle effect_handle = SEQ_effect_handle_get(seq);
effect_handle.init(seq);
}
TextVars *data = seq->effectdata;
if (data->color[3] == 0.0f) {
copy_v4_fl(data->color, 1.0f);
data->shadow_color[3] = 1.0f;
}
return true;
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@ -908,8 +947,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
Image *ima;
for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
Sequence *seq;
BKE_scene_add_render_view(scene, STEREO_LEFT_NAME);
srv = scene->r.views.first;
BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix));
@ -918,23 +955,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
srv = scene->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
SEQ_ALL_BEGIN (scene->ed, seq) {
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
if (seq->strip && seq->strip->proxy && !seq->strip->proxy->storage) {
if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_DIR;
}
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
seq->strip->proxy->storage = SEQ_STORAGE_PROXY_CUSTOM_FILE;
}
}
#undef SEQ_USE_PROXY_CUSTOM_DIR
#undef SEQ_USE_PROXY_CUSTOM_FILE
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_update_proxy_cb, NULL);
}
SEQ_ALL_END;
}
for (screen = bmain->screens.first; screen; screen = screen->id.next) {
@ -1215,25 +1238,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->type != SEQ_TYPE_TEXT) {
continue;
}
if (seq->effectdata == NULL) {
struct SeqEffectHandle effect_handle = SEQ_effect_handle_get(seq);
effect_handle.init(seq);
}
TextVars *data = seq->effectdata;
if (data->color[3] == 0.0f) {
copy_v4_fl(data->color, 1.0f);
data->shadow_color[3] = 1.0f;
}
if (scene->ed) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_update_effectdata_cb, NULL);
}
SEQ_ALL_END;
}
/* Adding "Properties" region to DopeSheet */

View File

@ -1772,6 +1772,16 @@ static void do_versions_seq_set_cache_defaults(Editing *ed)
ed->recycle_max_cost = 10.0f;
}
static bool seq_update_flags_cb(Sequence *seq, void *UNUSED(user_data))
{
seq->flag &= ~(SEQ_FLAG_UNUSED_6 | SEQ_FLAG_UNUSED_18 | SEQ_FLAG_UNUSED_19 | SEQ_FLAG_UNUSED_21);
if (seq->type == SEQ_TYPE_SPEED) {
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
s->flags &= ~(SEQ_SPEED_UNUSED_1);
}
return true;
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@ -3447,16 +3457,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (scene->ed) {
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
seq->flag &= ~(SEQ_FLAG_UNUSED_6 | SEQ_FLAG_UNUSED_18 | SEQ_FLAG_UNUSED_19 |
SEQ_FLAG_UNUSED_21);
if (seq->type == SEQ_TYPE_SPEED) {
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
s->flags &= ~(SEQ_SPEED_UNUSED_1);
}
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_update_flags_cb, NULL);
}
}

View File

@ -482,6 +482,22 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
ob->track = NULL;
}
static bool seq_set_alpha_mode_cb(Sequence *seq, void *UNUSED(user_data))
{
if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) {
seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
return true;
}
static bool seq_set_blend_mode_cb(Sequence *seq, void *UNUSED(user_data))
{
if (seq->blend_mode == 0) {
seq->blend_opacity = 100.0f;
}
return true;
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
{
@ -1228,7 +1244,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
if (bmain->versionfile <= 235) {
Tex *tex = bmain->textures.first;
Scene *sce = bmain->scenes.first;
Sequence *seq;
Editing *ed;
while (tex) {
@ -1240,12 +1255,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
while (sce) {
ed = sce->ed;
if (ed) {
SEQ_ALL_BEGIN (sce->ed, seq) {
if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) {
seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
}
SEQ_ALL_END;
SEQ_for_each_callback(&sce->ed->seqbase, seq_set_alpha_mode_cb, NULL);
}
sce = sce->id.next;
@ -2404,15 +2414,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 245, 14)) {
Scene *sce;
Sequence *seq;
for (sce = bmain->scenes.first; sce; sce = sce->id.next) {
SEQ_ALL_BEGIN (sce->ed, seq) {
if (seq->blend_mode == 0) {
seq->blend_opacity = 100.0f;
}
if (sce->ed) {
SEQ_for_each_callback(&sce->ed->seqbase, seq_set_blend_mode_cb, NULL);
}
SEQ_ALL_END;
}
}

View File

@ -112,6 +112,7 @@
#include "DEG_depsgraph_build.h"
#include "SEQ_iterator.h"
#include "SEQ_sequencer.h"
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_rna.h"
@ -2032,6 +2033,27 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation)
});
}
static bool seq_node_build_cb(Sequence *seq, void *user_data)
{
DepsgraphNodeBuilder *nb = (DepsgraphNodeBuilder *)user_data;
nb->build_idproperties(seq->prop);
if (seq->sound != nullptr) {
nb->build_sound(seq->sound);
}
if (seq->scene != nullptr) {
nb->build_scene_parameters(seq->scene);
}
if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
nb->build_scene_sequencer(seq->scene);
}
ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
nb->build_scene_speakers(seq->scene, sequence_view_layer);
}
/* TODO(sergey): Movie clip, scene, camera, mask. */
return true;
}
void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
{
if (scene->ed == nullptr) {
@ -2046,28 +2068,10 @@ void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
NodeType::SEQUENCER,
OperationCode::SEQUENCES_EVAL,
[scene_cow](::Depsgraph *depsgraph) {
BKE_scene_eval_sequencer_sequences(depsgraph, scene_cow);
SEQ_eval_sequences(depsgraph, scene_cow, &scene_cow->ed->seqbase);
});
/* Make sure data for sequences is in the graph. */
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
build_idproperties(seq->prop);
if (seq->sound != nullptr) {
build_sound(seq->sound);
}
if (seq->scene != nullptr) {
build_scene_parameters(seq->scene);
}
if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
build_scene_sequencer(seq->scene);
}
ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
build_scene_speakers(seq->scene, sequence_view_layer);
}
/* TODO(sergey): Movie clip, scene, camera, mask. */
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_node_build_cb, this);
}
void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)

View File

@ -2769,6 +2769,45 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0);
}
using Seq_build_prop_cb_data = struct Seq_build_prop_cb_data {
DepsgraphRelationBuilder *builder;
ComponentKey sequencer_key;
bool has_audio_strips;
};
static bool seq_build_prop_cb(Sequence *seq, void *user_data)
{
Seq_build_prop_cb_data *cd = (Seq_build_prop_cb_data *)user_data;
cd->builder->build_idproperties(seq->prop);
if (seq->sound != nullptr) {
cd->builder->build_sound(seq->sound);
ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
cd->builder->add_relation(sound_key, cd->sequencer_key, "Sound -> Sequencer");
cd->has_audio_strips = true;
}
if (seq->scene != nullptr) {
cd->builder->build_scene_parameters(seq->scene);
/* This is to support 3D audio. */
cd->has_audio_strips = true;
}
if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
cd->builder->build_scene_sequencer(seq->scene);
ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO);
cd->builder->add_relation(
sequence_scene_audio_key, cd->sequencer_key, "Sequence Scene Audio -> Sequencer");
ComponentKey sequence_scene_key(&seq->scene->id, NodeType::SEQUENCER);
cd->builder->add_relation(
sequence_scene_key, cd->sequencer_key, "Sequence Scene -> Sequencer");
}
ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
cd->builder->build_scene_speakers(seq->scene, sequence_view_layer);
}
/* TODO(sergey): Movie clip, camera, mask. */
return true;
}
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
{
if (scene->ed == nullptr) {
@ -2781,36 +2820,11 @@ void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
/* Make sure dependencies from sequences data goes to the sequencer evaluation. */
ComponentKey sequencer_key(&scene->id, NodeType::SEQUENCER);
Sequence *seq;
bool has_audio_strips = false;
SEQ_ALL_BEGIN (scene->ed, seq) {
build_idproperties(seq->prop);
if (seq->sound != nullptr) {
build_sound(seq->sound);
ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
add_relation(sound_key, sequencer_key, "Sound -> Sequencer");
has_audio_strips = true;
}
if (seq->scene != nullptr) {
build_scene_parameters(seq->scene);
/* This is to support 3D audio. */
has_audio_strips = true;
}
if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
build_scene_sequencer(seq->scene);
ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO);
add_relation(sequence_scene_audio_key, sequencer_key, "Sequence Scene Audio -> Sequencer");
ComponentKey sequence_scene_key(&seq->scene->id, NodeType::SEQUENCER);
add_relation(sequence_scene_key, sequencer_key, "Sequence Scene -> Sequencer");
}
ViewLayer *sequence_view_layer = BKE_view_layer_default_render(seq->scene);
build_scene_speakers(seq->scene, sequence_view_layer);
}
/* TODO(sergey): Movie clip, camera, mask. */
}
SEQ_ALL_END;
if (has_audio_strips) {
Seq_build_prop_cb_data cb_data = {this, sequencer_key, false};
SEQ_for_each_callback(&scene->ed->seqbase, seq_build_prop_cb, &cb_data);
if (cb_data.has_audio_strips) {
add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio");
}
}

View File

@ -38,33 +38,43 @@ SequencerBackup::SequencerBackup(const Depsgraph *depsgraph) : depsgraph(depsgra
{
}
static bool seq_init_cb(Sequence *seq, void *user_data)
{
SequencerBackup *sb = (SequencerBackup *)user_data;
SequenceBackup sequence_backup(sb->depsgraph);
sequence_backup.init_from_sequence(seq);
if (!sequence_backup.isEmpty()) {
const SessionUUID &session_uuid = seq->runtime.session_uuid;
BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
sb->sequences_backup.add(session_uuid, sequence_backup);
}
return true;
}
void SequencerBackup::init_from_scene(Scene *scene)
{
Sequence *sequence;
SEQ_ALL_BEGIN (scene->ed, sequence) {
SequenceBackup sequence_backup(depsgraph);
sequence_backup.init_from_sequence(sequence);
if (!sequence_backup.isEmpty()) {
const SessionUUID &session_uuid = sequence->runtime.session_uuid;
BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
sequences_backup.add(session_uuid, sequence_backup);
}
if (scene->ed != nullptr) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_init_cb, this);
}
SEQ_ALL_END;
}
static bool seq_restore_cb(Sequence *seq, void *user_data)
{
SequencerBackup *sb = (SequencerBackup *)user_data;
const SessionUUID &session_uuid = seq->runtime.session_uuid;
BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
SequenceBackup *sequence_backup = sb->sequences_backup.lookup_ptr(session_uuid);
if (sequence_backup != nullptr) {
sequence_backup->restore_to_sequence(seq);
}
return true;
}
void SequencerBackup::restore_to_scene(Scene *scene)
{
Sequence *sequence;
SEQ_ALL_BEGIN (scene->ed, sequence) {
const SessionUUID &session_uuid = sequence->runtime.session_uuid;
BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(session_uuid);
if (sequence_backup != nullptr) {
sequence_backup->restore_to_sequence(sequence);
}
if (scene->ed != nullptr) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_restore_cb, this);
}
SEQ_ALL_END;
/* Cleanup audio while the scene is still known. */
for (SequenceBackup &sequence_backup : sequences_backup.values()) {
if (sequence_backup.scene_sound != nullptr) {

View File

@ -207,7 +207,7 @@ static void SOUND_OT_open_mono(wmOperatorType *ot)
static void sound_update_animation_flags(Scene *scene);
static int sound_update_animation_flags_fn(Sequence *seq, void *user_data)
static bool sound_update_animation_flags_fn(Sequence *seq, void *user_data)
{
struct FCurve *fcu;
Scene *scene = (Scene *)user_data;
@ -244,24 +244,22 @@ static int sound_update_animation_flags_fn(Sequence *seq, void *user_data)
sound_update_animation_flags(seq->scene);
}
return 0;
return true;
}
static void sound_update_animation_flags(Scene *scene)
{
struct FCurve *fcu;
bool driven;
Sequence *seq;
if (scene->id.tag & LIB_TAG_DOIT) {
return;
}
scene->id.tag |= LIB_TAG_DOIT;
SEQ_ALL_BEGIN (scene->ed, seq) {
SEQ_recursive_apply(seq, sound_update_animation_flags_fn, scene);
if (scene->ed != NULL) {
SEQ_for_each_callback(&scene->ed->seqbase, sound_update_animation_flags_fn, scene);
}
SEQ_ALL_END;
fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
if (fcu || driven) {

View File

@ -2980,6 +2980,22 @@ static int sequencer_export_subtitles_invoke(bContext *C,
return OPERATOR_RUNNING_MODAL;
}
typedef struct Seq_get_text_cb_data {
ListBase *text_seq;
Scene *scene;
} Seq_get_text_cb_data;
static bool seq_get_text_strip_cb(Sequence *seq, void *user_data)
{
Seq_get_text_cb_data *cd = (Seq_get_text_cb_data *)user_data;
/* Only text strips that are not muted and don't end with negative frame. */
if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) &&
(seq->enddisp > cd->scene->r.sfra)) {
BLI_addtail(cd->text_seq, MEM_dupallocN(seq));
}
return true;
}
static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@ -3011,14 +3027,10 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
/* Only text strips that are not muted and don't end with negative frame. */
SEQ_ALL_BEGIN (ed, seq) {
if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) &&
(seq->enddisp > scene->r.sfra)) {
BLI_addtail(&text_seq, MEM_dupallocN(seq));
}
if (ed != NULL) {
Seq_get_text_cb_data cb_data = {&text_seq, scene};
SEQ_for_each_callback(&ed->seqbase, seq_get_text_strip_cb, &cb_data);
}
SEQ_ALL_END;
if (BLI_listbase_is_empty(&text_seq)) {
BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export");

View File

@ -1185,6 +1185,14 @@ static void colormanage_check_colorspace_settings(
(void)what;
}
static bool seq_callback(Sequence *seq, void *UNUSED(user_data))
{
if (seq->strip) {
colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip");
}
return true;
}
void IMB_colormanagement_check_file_config(Main *bmain)
{
Scene *scene;
@ -1217,13 +1225,9 @@ void IMB_colormanagement_check_file_config(Main *bmain)
}
/* check sequencer strip input color space settings */
Sequence *seq;
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->strip) {
colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip");
}
if (scene->ed != NULL) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_callback, NULL);
}
SEQ_ALL_END;
}
/* ** check input color space settings ** */

View File

@ -597,6 +597,27 @@ static const EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_ite
return items;
}
typedef struct Seq_colorspace_cb_data {
ColorManagedColorspaceSettings *colorspace_settings;
Sequence *r_seq;
} Seq_colorspace_cb_data;
static bool seq_find_colorspace_settings_cb(Sequence *seq, void *user_data)
{
Seq_colorspace_cb_data *cd = (Seq_colorspace_cb_data *)user_data;
if (seq->strip && &seq->strip->colorspace_settings == cd->colorspace_settings) {
cd->r_seq = seq;
return false;
}
return true;
}
static bool seq_free_anim_cb(Sequence *seq, void *UNUSED(user_data))
{
SEQ_relations_sequence_free_anim(seq);
return true;
}
static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain,
Scene *UNUSED(scene),
PointerRNA *ptr)
@ -629,20 +650,14 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain,
if (scene->ed) {
ColorManagedColorspaceSettings *colorspace_settings = (ColorManagedColorspaceSettings *)
ptr->data;
Sequence *seq;
bool seq_found = false;
Seq_colorspace_cb_data cb_data = {colorspace_settings, NULL};
if (&scene->sequencer_colorspace_settings != colorspace_settings) {
SEQ_ALL_BEGIN (scene->ed, seq) {
if (seq->strip && &seq->strip->colorspace_settings == colorspace_settings) {
seq_found = true;
break;
}
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_find_colorspace_settings_cb, &cb_data);
}
Sequence *seq = cb_data.r_seq;
if (seq_found) {
if (seq) {
SEQ_relations_sequence_free_anim(seq);
if (seq->strip->proxy && seq->strip->proxy->anim) {
@ -653,10 +668,7 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain,
SEQ_relations_invalidate_cache_raw(scene, seq);
}
else {
SEQ_ALL_BEGIN (scene->ed, seq) {
SEQ_relations_sequence_free_anim(seq);
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, seq_free_anim_cb, NULL);
}
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);

View File

@ -495,15 +495,15 @@ static void rna_Sequence_use_proxy_set(PointerRNA *ptr, bool value)
SEQ_proxy_set(seq, value != 0);
}
static int transform_seq_cmp_fn(Sequence *seq, void *arg_pt)
static bool transform_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
if (seq->strip && seq->strip->transform == data->data) {
data->seq = seq;
return -1; /* done so bail out */
return false; /* done so bail out */
}
return 1;
return true;
}
static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transform)
@ -514,7 +514,7 @@ static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transfor
data.data = transform;
/* irritating we need to search for our sequence! */
SEQ_seqbase_recursive_apply(&ed->seqbase, transform_seq_cmp_fn, &data);
SEQ_for_each_callback(&ed->seqbase, transform_seq_cmp_fn, &data);
return data.seq;
}
@ -547,15 +547,15 @@ static void rna_SequenceTransform_update(Main *UNUSED(bmain),
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
}
static int crop_seq_cmp_fn(Sequence *seq, void *arg_pt)
static bool crop_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
if (seq->strip && seq->strip->crop == data->data) {
data->seq = seq;
return -1; /* done so bail out */
return false; /* done so bail out */
}
return 1;
return true;
}
static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop)
@ -566,7 +566,7 @@ static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop)
data.data = crop;
/* irritating we need to search for our sequence! */
SEQ_seqbase_recursive_apply(&ed->seqbase, crop_seq_cmp_fn, &data);
SEQ_for_each_callback(&ed->seqbase, crop_seq_cmp_fn, &data);
return data.seq;
}
@ -935,15 +935,15 @@ static void rna_Sequence_sound_update(Main *bmain, Scene *scene, PointerRNA *UNU
DEG_relations_tag_update(bmain);
}
static int seqproxy_seq_cmp_fn(Sequence *seq, void *arg_pt)
static bool seqproxy_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
if (seq->strip && seq->strip->proxy == data->data) {
data->seq = seq;
return -1; /* done so bail out */
return false; /* done so bail out */
}
return 1;
return true;
}
static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
@ -953,7 +953,7 @@ static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
data.seq = NULL;
data.data = proxy;
SEQ_seqbase_recursive_apply(&ed->seqbase, seqproxy_seq_cmp_fn, &data);
SEQ_for_each_callback(&ed->seqbase, seqproxy_seq_cmp_fn, &data);
return data.seq;
}
@ -988,7 +988,7 @@ static void rna_Sequence_opacity_set(PointerRNA *ptr, float value)
seq->blend_opacity = value * 100.0f;
}
static int colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt)
static bool colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
@ -999,12 +999,12 @@ static int colbalance_seq_cmp_fn(Sequence *seq, void *arg_pt)
if (&cbmd->color_balance == data->data) {
data->seq = seq;
data->smd = smd;
return -1; /* done so bail out */
return false; /* done so bail out */
}
}
}
return 1;
return true;
}
static Sequence *sequence_get_by_colorbalance(Editing *ed,
@ -1018,7 +1018,7 @@ static Sequence *sequence_get_by_colorbalance(Editing *ed,
data.data = cb;
/* irritating we need to search for our sequence! */
SEQ_seqbase_recursive_apply(&ed->seqbase, colbalance_seq_cmp_fn, &data);
SEQ_for_each_callback(&ed->seqbase, colbalance_seq_cmp_fn, &data);
*r_smd = data.smd;
@ -1122,16 +1122,16 @@ static void rna_SequenceEditor_overlay_frame_set(PointerRNA *ptr, int value)
}
}
static int modifier_seq_cmp_fn(Sequence *seq, void *arg_pt)
static bool modifier_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
if (BLI_findindex(&seq->modifiers, data->data) != -1) {
data->seq = seq;
return -1; /* done so bail out */
return false; /* done so bail out */
}
return 1;
return true;
}
static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd)
@ -1142,7 +1142,7 @@ static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd
data.data = smd;
/* irritating we need to search for our sequence! */
SEQ_seqbase_recursive_apply(&ed->seqbase, modifier_seq_cmp_fn, &data);
SEQ_for_each_callback(&ed->seqbase, modifier_seq_cmp_fn, &data);
return data.seq;
}

View File

@ -39,23 +39,7 @@ struct Sequence;
SEQ_iterator_ensure(collection, &iter, &var) && var != NULL; \
var = SEQ_iterator_yield(&iter))
#define SEQ_ALL_BEGIN(ed, var) \
{ \
if (ed != NULL) { \
SeqCollection *all_strips = SEQ_query_all_strips_recursive(&ed->seqbase); \
GSetIterator gsi; \
GSET_ITER (gsi, all_strips->set) { \
var = (Sequence *)(BLI_gsetIterator_getKey(&gsi));
#define SEQ_ALL_END \
} \
SEQ_collection_free(all_strips); \
} \
} \
((void)0)
typedef struct SeqCollection {
struct SeqCollection *next, *prev;
struct GSet *set;
} SeqCollection;
@ -70,6 +54,11 @@ bool SEQ_iterator_ensure(SeqCollection *collection,
struct Sequence **r_seq);
struct Sequence *SEQ_iterator_yield(SeqIterator *iterator);
/* Callback format for the for_each function below. */
typedef bool (*SeqForEachFunc)(struct Sequence *seq, void *user_data);
void SEQ_for_each_callback(struct ListBase *seqbase, SeqForEachFunc callback, void *user_data);
SeqCollection *SEQ_collection_create(const char *name);
SeqCollection *SEQ_collection_duplicate(SeqCollection *collection);
uint SEQ_collection_len(const SeqCollection *collection);
@ -90,8 +79,8 @@ SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection));
SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase);
SeqCollection *SEQ_query_all_strips(ListBase *seqbase);
SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
SeqCollection *SEQ_query_all_strips(struct ListBase *seqbase);
SeqCollection *SEQ_query_all_strips_recursive(struct ListBase *seqbase);
void SEQ_query_strip_effect_chain(struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection);

View File

@ -29,6 +29,11 @@ extern "C" {
#include "DNA_scene_types.h"
struct BlendWriter;
struct BlendDataReader;
struct BlendLibReader;
struct BlendExpander;
struct Depsgraph;
struct Editing;
struct Scene;
struct Sequence;
@ -83,6 +88,21 @@ void SEQ_sequence_base_dupli_recursive(const struct Scene *scene_src,
int dupe_flag,
const int flag);
/* Read and Write functions for .blend file data */
void SEQ_blend_write(struct BlendWriter *writer, struct ListBase *seqbase);
void SEQ_blend_read(struct BlendDataReader *reader, struct ListBase *seqbase);
void SEQ_blend_read_lib(struct BlendLibReader *reader,
struct Scene *scene,
struct ListBase *seqbase);
void SEQ_blend_read_expand(struct BlendExpander *expander, struct ListBase *seqbase);
/* Depsgraph update function */
void SEQ_eval_sequences(struct Depsgraph *depsgraph,
struct Scene *scene,
struct ListBase *seqbase);
/* Defined in sequence_lookup.c */
typedef enum eSequenceLookupTag {

View File

@ -56,12 +56,6 @@ void SEQ_set_scale_to_fit(const struct Sequence *seq,
const int preview_width,
const int preview_height,
const eSeqImageFitMethod fit_method);
int SEQ_seqbase_recursive_apply(struct ListBase *seqbase,
int (*apply_fn)(struct Sequence *seq, void *),
void *arg);
int SEQ_recursive_apply(struct Sequence *seq,
int (*apply_fn)(struct Sequence *, void *),
void *arg);
void SEQ_ensure_unique_name(struct Sequence *seq, struct Scene *scene);
#ifdef __cplusplus

View File

@ -71,7 +71,7 @@ void SEQ_clipboard_free(void)
for (seq = seqbase_clipboard.first; seq; seq = nseq) {
nseq = seq->next;
seq_free_sequence_recurse(NULL, seq, false);
seq_free_sequence_recurse(NULL, seq, false, true);
}
BLI_listbase_clear(&seqbase_clipboard);
}

View File

@ -90,6 +90,37 @@ Sequence *SEQ_iterator_yield(SeqIterator *iterator)
return seq;
}
static bool seq_for_each_recursive(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
{
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (!callback(seq, user_data)) {
/* Callback signaled stop, return. */
return false;
}
if (seq->type == SEQ_TYPE_META) {
if (!seq_for_each_recursive(&seq->seqbase, callback, user_data)) {
return false;
}
}
}
return true;
}
/**
* Utility function to recursivily iterate through all sequence strips in a seqbase list.
* Uses callback to do operations on each sequence element.
* The callback can stop the iteration if needed.
*
* \param seqbase: ListBase of sequences to be iterated over
* \param callback: query function callback, returns false if iteration should stop
* \param user_data: pointer to user data that can be used in the callback function
*
*/
void SEQ_for_each_callback(ListBase *seqbase, SeqForEachFunc callback, void *user_data)
{
seq_for_each_recursive(seqbase, callback, user_data);
}
/**
* Free strip collection.
*
@ -222,19 +253,15 @@ void SEQ_collection_expand(ListBase *seqbase,
SeqCollection *collection))
{
/* Collect expanded results for each sequence in provided SeqIteratorCollection. */
ListBase expand_collections = {0};
SeqCollection *query_matches = SEQ_collection_create(__func__);
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, collection) {
SeqCollection *expand_collection = SEQ_query_by_reference(seq, seqbase, seq_query_func);
BLI_addtail(&expand_collections, expand_collection);
SEQ_collection_merge(query_matches, SEQ_query_by_reference(seq, seqbase, seq_query_func));
}
/* Merge all expanded results in provided SeqIteratorCollection. */
LISTBASE_FOREACH_MUTABLE (SeqCollection *, expand_collection, &expand_collections) {
BLI_remlink(&expand_collections, expand_collection);
SEQ_collection_merge(collection, expand_collection);
}
SEQ_collection_merge(collection, query_matches);
}
/**
@ -255,6 +282,16 @@ SeqCollection *SEQ_collection_duplicate(SeqCollection *collection)
/** \} */
static void query_all_strips_recursive(ListBase *seqbase, SeqCollection *collection)
{
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (seq->type == SEQ_TYPE_META) {
query_all_strips_recursive(&seq->seqbase, collection);
}
SEQ_collection_append_strip(seq, collection);
}
}
/**
* Query all strips in seqbase and nested meta strips.
*
@ -266,7 +303,7 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase)
SeqCollection *collection = SEQ_collection_create(__func__);
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (seq->type == SEQ_TYPE_META) {
SEQ_collection_merge(collection, SEQ_query_all_strips_recursive(&seq->seqbase));
query_all_strips_recursive(&seq->seqbase, collection);
}
SEQ_collection_append_strip(seq, collection);
}
@ -282,9 +319,7 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase)
SeqCollection *SEQ_query_all_strips(ListBase *seqbase)
{
SeqCollection *collection = SEQ_collection_create(__func__);
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
SEQ_collection_append_strip(seq, collection);
}
query_all_strips_recursive(seqbase, collection);
return collection;
}

View File

@ -576,7 +576,7 @@ void SEQ_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop)
IMB_anim_index_rebuild_finish(context->index_context, stop);
}
seq_free_sequence_recurse(NULL, context->seq, true);
seq_free_sequence_recurse(NULL, context->seq, true, true);
MEM_freeN(context);
}

View File

@ -24,11 +24,14 @@
* \ingroup bke
*/
#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@ -44,14 +47,19 @@
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "SEQ_edit.h"
#include "SEQ_effects.h"
#include "SEQ_iterator.h"
#include "SEQ_modifier.h"
#include "SEQ_proxy.h"
#include "SEQ_relations.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
#include "SEQ_sound.h"
#include "SEQ_utils.h"
#include "BLO_read_write.h"
#include "image_cache.h"
#include "prefetch.h"
#include "sequencer.h"
@ -217,16 +225,19 @@ void SEQ_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata
/* cache must be freed before calling this function
* since it leaves the seqbase in an invalid state */
void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user)
void seq_free_sequence_recurse(Scene *scene,
Sequence *seq,
const bool do_id_user,
const bool do_clean_animdata)
{
Sequence *iseq, *iseq_next;
for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
iseq_next = iseq->next;
seq_free_sequence_recurse(scene, iseq, do_id_user);
seq_free_sequence_recurse(scene, iseq, do_id_user, do_clean_animdata);
}
seq_sequence_free_ex(scene, seq, false, do_id_user, true);
seq_sequence_free_ex(scene, seq, false, do_id_user, do_clean_animdata);
}
Editing *SEQ_editing_get(Scene *scene, bool alloc)
@ -255,7 +266,6 @@ Editing *SEQ_editing_ensure(Scene *scene)
void SEQ_editing_free(Scene *scene, const bool do_id_user)
{
Editing *ed = scene->ed;
Sequence *seq;
if (ed == NULL) {
return;
@ -264,11 +274,10 @@ void SEQ_editing_free(Scene *scene, const bool do_id_user)
seq_prefetch_free(scene);
seq_cache_destruct(scene);
SEQ_ALL_BEGIN (ed, seq) {
/* handle cache freeing above */
seq_sequence_free_ex(scene, seq, false, do_id_user, false);
/* handle cache freeing above */
LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &ed->seqbase) {
seq_free_sequence_recurse(scene, seq, do_id_user, false);
}
SEQ_ALL_END;
BLI_freelistN(&ed->metastack);
SEQ_sequence_lookup_free(scene);
@ -732,3 +741,315 @@ SequencerToolSettings *SEQ_tool_settings_copy(SequencerToolSettings *tool_settin
}
/** \} */
static bool seq_set_strip_done_cb(Sequence *seq, void *UNUSED(userdata))
{
if (seq->strip) {
seq->strip->done = false;
}
return true;
}
static bool seq_write_data_cb(Sequence *seq, void *userdata)
{
BlendWriter *writer = (BlendWriter *)userdata;
BLO_write_struct(writer, Sequence, seq);
if (seq->strip && seq->strip->done == 0) {
/* write strip with 'done' at 0 because readfile */
// TODO this doesn't depend on the `Strip` data to be present?
if (seq->effectdata) {
switch (seq->type) {
case SEQ_TYPE_COLOR:
BLO_write_struct(writer, SolidColorVars, seq->effectdata);
break;
case SEQ_TYPE_SPEED:
BLO_write_struct(writer, SpeedControlVars, seq->effectdata);
break;
case SEQ_TYPE_WIPE:
BLO_write_struct(writer, WipeVars, seq->effectdata);
break;
case SEQ_TYPE_GLOW:
BLO_write_struct(writer, GlowVars, seq->effectdata);
break;
case SEQ_TYPE_TRANSFORM:
BLO_write_struct(writer, TransformVars, seq->effectdata);
break;
case SEQ_TYPE_GAUSSIAN_BLUR:
BLO_write_struct(writer, GaussianBlurVars, seq->effectdata);
break;
case SEQ_TYPE_TEXT:
BLO_write_struct(writer, TextVars, seq->effectdata);
break;
case SEQ_TYPE_COLORMIX:
BLO_write_struct(writer, ColorMixVars, seq->effectdata);
break;
}
}
BLO_write_struct(writer, Stereo3dFormat, seq->stereo3d_format);
Strip *strip = seq->strip;
BLO_write_struct(writer, Strip, strip);
if (strip->crop) {
BLO_write_struct(writer, StripCrop, strip->crop);
}
if (strip->transform) {
BLO_write_struct(writer, StripTransform, strip->transform);
}
if (strip->proxy) {
BLO_write_struct(writer, StripProxy, strip->proxy);
}
if (seq->type == SEQ_TYPE_IMAGE) {
BLO_write_struct_array(writer,
StripElem,
MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem),
strip->stripdata);
}
else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
BLO_write_struct(writer, StripElem, strip->stripdata);
}
strip->done = true;
}
if (seq->prop) {
IDP_BlendWrite(writer, seq->prop);
}
SEQ_modifier_blend_write(writer, &seq->modifiers);
return true;
}
void SEQ_blend_write(BlendWriter *writer, ListBase *seqbase)
{
/* reset write flags */
SEQ_for_each_callback(seqbase, seq_set_strip_done_cb, NULL);
SEQ_for_each_callback(seqbase, seq_write_data_cb, writer);
}
static bool seq_read_data_cb(Sequence *seq, void *user_data)
{
BlendDataReader *reader = (BlendDataReader *)user_data;
/* Do as early as possible, so that other parts of reading can rely on valid session UUID. */
SEQ_relations_session_uuid_generate(seq);
BLO_read_data_address(reader, &seq->seq1);
BLO_read_data_address(reader, &seq->seq2);
BLO_read_data_address(reader, &seq->seq3);
/* a patch: after introduction of effects with 3 input strips */
if (seq->seq3 == NULL) {
seq->seq3 = seq->seq2;
}
BLO_read_data_address(reader, &seq->effectdata);
BLO_read_data_address(reader, &seq->stereo3d_format);
if (seq->type & SEQ_TYPE_EFFECT) {
seq->flag |= SEQ_EFFECT_NOT_LOADED;
}
if (seq->type == SEQ_TYPE_TEXT) {
TextVars *t = seq->effectdata;
t->text_blf_id = SEQ_FONT_NOT_LOADED;
}
BLO_read_data_address(reader, &seq->prop);
IDP_BlendDataRead(reader, &seq->prop);
BLO_read_data_address(reader, &seq->strip);
if (seq->strip && seq->strip->done == 0) {
seq->strip->done = true;
if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
BLO_read_data_address(reader, &seq->strip->stripdata);
}
else {
seq->strip->stripdata = NULL;
}
BLO_read_data_address(reader, &seq->strip->crop);
BLO_read_data_address(reader, &seq->strip->transform);
BLO_read_data_address(reader, &seq->strip->proxy);
if (seq->strip->proxy) {
seq->strip->proxy->anim = NULL;
}
else if (seq->flag & SEQ_USE_PROXY) {
SEQ_proxy_set(seq, true);
}
/* need to load color balance to it could be converted to modifier */
BLO_read_data_address(reader, &seq->strip->color_balance);
}
SEQ_modifier_blend_read_data(reader, &seq->modifiers);
return true;
}
void SEQ_blend_read(BlendDataReader *reader, ListBase *seqbase)
{
SEQ_for_each_callback(seqbase, seq_read_data_cb, reader);
}
typedef struct Read_lib_data {
BlendLibReader *reader;
Scene *scene;
} Read_lib_data;
static bool seq_read_lib_cb(Sequence *seq, void *user_data)
{
Read_lib_data *data = (Read_lib_data *)user_data;
BlendLibReader *reader = data->reader;
Scene *sce = data->scene;
IDP_BlendReadLib(reader, seq->prop);
if (seq->ipo) {
/* XXX: deprecated - old animation system. */
BLO_read_id_address(reader, sce->id.lib, &seq->ipo);
}
seq->scene_sound = NULL;
if (seq->scene) {
BLO_read_id_address(reader, sce->id.lib, &seq->scene);
seq->scene_sound = NULL;
}
if (seq->clip) {
BLO_read_id_address(reader, sce->id.lib, &seq->clip);
}
if (seq->mask) {
BLO_read_id_address(reader, sce->id.lib, &seq->mask);
}
if (seq->scene_camera) {
BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera);
}
if (seq->sound) {
seq->scene_sound = NULL;
if (seq->type == SEQ_TYPE_SOUND_HD) {
seq->type = SEQ_TYPE_SOUND_RAM;
}
else {
BLO_read_id_address(reader, sce->id.lib, &seq->sound);
}
if (seq->sound) {
id_us_plus_no_lib((ID *)seq->sound);
seq->scene_sound = NULL;
}
}
if (seq->type == SEQ_TYPE_TEXT) {
TextVars *t = seq->effectdata;
BLO_read_id_address(reader, sce->id.lib, &t->text_font);
}
BLI_listbase_clear(&seq->anims);
SEQ_modifier_blend_read_lib(reader, sce, &seq->modifiers);
return true;
}
void SEQ_blend_read_lib(BlendLibReader *reader, Scene *scene, ListBase *seqbase)
{
Read_lib_data data = {reader, scene};
SEQ_for_each_callback(seqbase, seq_read_lib_cb, &data);
}
static bool seq_blend_read_expand(Sequence *seq, void *user_data)
{
BlendExpander *expander = (BlendExpander *)user_data;
IDP_BlendReadExpand(expander, seq->prop);
if (seq->scene) {
BLO_expand(expander, seq->scene);
}
if (seq->scene_camera) {
BLO_expand(expander, seq->scene_camera);
}
if (seq->clip) {
BLO_expand(expander, seq->clip);
}
if (seq->mask) {
BLO_expand(expander, seq->mask);
}
if (seq->sound) {
BLO_expand(expander, seq->sound);
}
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
TextVars *data = seq->effectdata;
BLO_expand(expander, data->text_font);
}
return true;
}
void SEQ_blend_read_expand(BlendExpander *expander, ListBase *seqbase)
{
SEQ_for_each_callback(seqbase, seq_blend_read_expand, expander);
}
/* Depsgraph update functions. */
static bool seq_disable_sound_strips_cb(Sequence *seq, void *user_data)
{
Scene *scene = (Scene *)user_data;
if (seq->scene_sound != NULL) {
BKE_sound_remove_scene_sound(scene, seq->scene_sound);
seq->scene_sound = NULL;
}
return true;
}
static bool seq_update_seq_cb(Sequence *seq, void *user_data)
{
Scene *scene = (Scene *)user_data;
if (seq->scene_sound == NULL) {
if (seq->sound != NULL) {
seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
}
else if (seq->type == SEQ_TYPE_SCENE) {
if (seq->scene != NULL) {
BKE_sound_ensure_scene(seq->scene);
seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq);
}
}
}
if (seq->scene_sound != NULL) {
/* Make sure changing volume via sequence's properties panel works correct.
*
* Ideally, the entire BKE_scene_update_sound() will happen from a dependency graph, so
* then it is no longer needed to do such manual forced updates. */
if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) {
BKE_sound_set_scene_volume(seq->scene, seq->scene->audio.volume);
if ((seq->flag & SEQ_SCENE_STRIPS) == 0 && seq->scene->sound_scene != NULL &&
seq->scene->ed != NULL) {
SEQ_for_each_callback(&seq->scene->ed->seqbase, seq_disable_sound_strips_cb, seq->scene);
}
}
if (seq->sound != NULL) {
if (scene->id.recalc & ID_RECALC_AUDIO || seq->sound->id.recalc & ID_RECALC_AUDIO) {
BKE_sound_update_scene_sound(seq->scene_sound, seq->sound);
}
}
BKE_sound_set_scene_sound_volume(
seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0);
BKE_sound_set_scene_sound_pitch(
seq->scene_sound, seq->pitch, (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0);
BKE_sound_set_scene_sound_pan(
seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0);
}
return true;
}
/* Evaluate parts of sequences which needs to be done as a part of a dependency graph evaluation.
* This does NOT include actual rendering of the strips, but rather makes them up-to-date for
* animation playback and makes them ready for the sequencer's rendering pipeline to render them.
*/
void SEQ_eval_sequences(Depsgraph *depsgraph, Scene *scene, ListBase *seqbase)
{
DEG_debug_print_eval(depsgraph, __func__, scene->id.name, scene);
BKE_sound_ensure_scene(scene);
SEQ_for_each_callback(seqbase, seq_update_seq_cb, scene);
SEQ_edit_update_muting(scene->ed);
SEQ_sound_update_bounds_all(scene);
}

View File

@ -30,7 +30,10 @@ extern "C" {
struct Scene;
struct Sequence;
void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, const bool do_id_user);
void seq_free_sequence_recurse(struct Scene *scene,
struct Sequence *seq,
const bool do_id_user,
const bool do_clean_animdata);
#ifdef __cplusplus
}

View File

@ -476,6 +476,24 @@ void SEQ_relations_session_uuid_generate(struct Sequence *sequence)
sequence->runtime.session_uuid = BLI_session_uuid_generate();
}
static bool get_uuids_cb(Sequence *seq, void *user_data)
{
struct GSet *used_uuids = (struct GSet *)user_data;
const SessionUUID *session_uuid = &seq->runtime.session_uuid;
if (!BLI_session_uuid_is_generated(session_uuid)) {
printf("Sequence %s does not have UUID generated.\n", seq->name);
return true;
}
if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
printf("Sequence %s has duplicate UUID generated.\n", seq->name);
return true;
}
BLI_gset_insert(used_uuids, (void *)session_uuid);
return true;
}
void SEQ_relations_check_uuids_unique_and_report(const Scene *scene)
{
if (scene->ed == NULL) {
@ -485,22 +503,7 @@ void SEQ_relations_check_uuids_unique_and_report(const Scene *scene)
struct GSet *used_uuids = BLI_gset_new(
BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
const Sequence *sequence;
SEQ_ALL_BEGIN (scene->ed, sequence) {
const SessionUUID *session_uuid = &sequence->runtime.session_uuid;
if (!BLI_session_uuid_is_generated(session_uuid)) {
printf("Sequence %s does not have UUID generated.\n", sequence->name);
continue;
}
if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
printf("Sequence %s has duplicate UUID generated.\n", sequence->name);
continue;
}
BLI_gset_insert(used_uuids, (void *)session_uuid);
}
SEQ_ALL_END;
SEQ_for_each_callback(&scene->ed->seqbase, get_uuids_cb, used_uuids);
BLI_gset_free(used_uuids, NULL);
}

View File

@ -133,12 +133,12 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
}
}
static int seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt)
static bool seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt)
{
if (seq->seqbase.first) {
seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
}
return 1;
return true;
}
void SEQ_sequence_base_unique_name_recursive(struct Scene *scene,
@ -167,7 +167,7 @@ void SEQ_sequence_base_unique_name_recursive(struct Scene *scene,
while (sui.match) {
sui.match = 0;
seqbase_unique_name(seqbasep, &sui);
SEQ_seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_fn, &sui);
SEQ_for_each_callback(seqbasep, seqbase_unique_name_recursive_fn, &sui);
}
SEQ_edit_sequence_name_set(scene, seq, sui.name_dest);
@ -573,34 +573,6 @@ void SEQ_set_scale_to_fit(const Sequence *seq,
}
}
int SEQ_seqbase_recursive_apply(ListBase *seqbase,
int (*apply_fn)(Sequence *seq, void *),
void *arg)
{
Sequence *iseq;
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
if (SEQ_recursive_apply(iseq, apply_fn, arg) == -1) {
return -1; /* bail out */
}
}
return 1;
}
int SEQ_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void *arg)
{
int ret = apply_fn(seq, arg);
if (ret == -1) {
return -1; /* bail out */
}
if (ret && seq->seqbase.first) {
ret = SEQ_seqbase_recursive_apply(&seq->seqbase, apply_fn, arg);
}
return ret;
}
/**
* Ensure, that provided Sequence has unique name. If animation data exists for this Sequence, it
* will be duplicated and mapped onto new name