VSE: Refactor VSE strip loading code

Isolate RNA and operator logic from functions that create strips.
 - Operator specific code was removed from `SeqLoadInfo` structure and
   `SEQ_add_*` functions.
 - Strip loading code was removed from RNA and operator functions.
 - `SEQ_add_*` API was unified to work on `SeqLoadData` struct.
   Only exception is image strip, which require files to be loaded
   separately to strip creation itself. This is not ideal, but I think
   it's acceptable.
 - Some functions and variables were refactored so the code reads
   better.

There are minor functional changes (coincidental bugfixes):
 - Operator errors are reported per-strip. Previously they were not
   reported at all?
 - `new_sound()` RNA API function now create sound with length of 1
   if source file does not exist. Previously it created strip with
   length of 0.
 - Replace selection operator property wasn't working correctly.
   Fixed in this patch.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D9760
This commit is contained in:
2021-03-02 12:08:16 +01:00
parent b279fef85d
commit bbb1936411
5 changed files with 775 additions and 646 deletions

View File

@@ -53,6 +53,7 @@
# include "SEQ_add.h"
# include "SEQ_edit.h"
# include "SEQ_effects.h"
# include "SEQ_relations.h"
# include "SEQ_render.h"
# include "SEQ_sequencer.h"
@@ -80,34 +81,6 @@ static void rna_Sequence_swap_internal(Sequence *seq_self,
}
}
static Sequence *alloc_generic_sequence(
ListBase *seqbase, const char *name, int frame_start, int channel, int type, const char *file)
{
Sequence *seq;
StripElem *se;
seq = SEQ_sequence_alloc(seqbase, frame_start, channel, type);
BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2);
SEQ_sequence_base_unique_name_recursive(seqbase, seq);
Strip *strip = seq->strip;
/* Don't allocate StripElem for clip, mask and scene types. This struct is not handled in
* seq_dupli() function. */
if (file && !ELEM(type, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK, SEQ_TYPE_SCENE)) {
strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem");
BLI_split_dirfile(file, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
SEQ_render_init_colorspace(seq);
}
else {
strip->stripdata = NULL;
}
return seq;
}
static Sequence *rna_Sequences_new_clip(ID *id,
ListBase *seqbase,
Main *bmain,
@@ -117,15 +90,10 @@ static Sequence *rna_Sequences_new_clip(ID *id,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
seq = alloc_generic_sequence(
seqbase, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->filepath);
seq->clip = clip;
seq->len = BKE_movieclip_get_duration(clip);
id_us_plus((ID *)clip);
SEQ_time_update_sequence_bounds(scene, seq);
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, NULL, frame_start, channel);
load_data.clip = clip;
Sequence *seq = SEQ_add_movieclip_strip(scene, seqbase, &load_data);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -165,15 +133,10 @@ static Sequence *rna_Sequences_new_mask(ID *id,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
seq = alloc_generic_sequence(seqbase, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name);
seq->mask = mask;
seq->len = BKE_mask_get_duration(mask);
id_us_plus((ID *)mask);
SEQ_time_update_sequence_bounds(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, NULL, frame_start, channel);
load_data.mask = mask;
Sequence *seq = SEQ_add_mask_strip(scene, seqbase, &load_data);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -202,15 +165,10 @@ static Sequence *rna_Sequences_new_scene(ID *id,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
seq = alloc_generic_sequence(seqbase, name, frame_start, channel, SEQ_TYPE_SCENE, NULL);
seq->scene = sce_seq;
seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
id_us_plus((ID *)sce_seq);
SEQ_time_update_sequence_bounds(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, NULL, frame_start, channel);
load_data.scene = sce_seq;
Sequence *seq = SEQ_add_scene_strip(scene, seqbase, &load_data);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -251,20 +209,17 @@ static Sequence *rna_Sequences_new_image(ID *id,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
seq = alloc_generic_sequence(seqbase, name, frame_start, channel, SEQ_TYPE_IMAGE, file);
seq->len = 1;
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, file, frame_start, channel);
load_data.image.len = 1;
Sequence *seq = SEQ_add_image_strip(bmain, scene, seqbase, &load_data);
if (seq->strip->stripdata->name[0] == '\0') {
BKE_report(reports, RPT_ERROR, "Sequences.new_image: unable to open image file");
BLI_remlink(seqbase, seq);
SEQ_sequence_free(scene, seq, true);
return NULL;
}
SEQ_time_update_sequence_bounds(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
char dir[FILE_MAX], filename[FILE_MAX];
BLI_split_dirfile(file, dir, filename, sizeof(dir), sizeof(filename));
SEQ_add_image_set_directory(seq, dir);
SEQ_add_image_load_file(seq, 0, filename);
SEQ_add_image_init_alpha_mode(seq);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -299,48 +254,47 @@ static Sequence *rna_Sequences_meta_new_image(ID *id,
id, &seq->seqbase, bmain, reports, name, file, channel, frame_start);
}
static Sequence *rna_Sequences_new_movie(
ID *id, ListBase *seqbase, const char *name, const char *file, int channel, int frame_start)
static Sequence *rna_Sequences_new_movie(ID *id,
ListBase *seqbase,
Main *bmain,
const char *name,
const char *file,
int channel,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
StripAnim *sanim;
seq = alloc_generic_sequence(seqbase, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
struct anim *an = openanim(file, IB_rect, 0, NULL);
if (an == NULL) {
/* Without anim, the strip gets duration 0, which makes it impossible to select in the UI. */
seq->len = 1;
}
else {
sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
BLI_addtail(&seq->anims, sanim);
sanim->anim = an;
seq->anim_preseek = IMB_anim_get_preseek(an);
seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
}
SEQ_time_update_sequence_bounds(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, file, frame_start, channel);
load_data.allow_invalid_file = true;
Sequence *seq = SEQ_add_movie_strip(bmain, scene, seqbase, &load_data);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
return seq;
}
static Sequence *rna_Sequences_editing_new_movie(
ID *id, Editing *ed, const char *name, const char *file, int channel, int frame_start)
static Sequence *rna_Sequences_editing_new_movie(ID *id,
Editing *ed,
Main *bmain,
const char *name,
const char *file,
int channel,
int frame_start)
{
return rna_Sequences_new_movie(id, &ed->seqbase, name, file, channel, frame_start);
return rna_Sequences_new_movie(id, &ed->seqbase, bmain, name, file, channel, frame_start);
}
static Sequence *rna_Sequences_meta_new_movie(
ID *id, Sequence *seq, const char *name, const char *file, int channel, int frame_start)
static Sequence *rna_Sequences_meta_new_movie(ID *id,
Sequence *seq,
Main *bmain,
const char *name,
const char *file,
int channel,
int frame_start)
{
return rna_Sequences_new_movie(id, &seq->seqbase, name, file, channel, frame_start);
return rna_Sequences_new_movie(id, &seq->seqbase, bmain, name, file, channel, frame_start);
}
# ifdef WITH_AUDASPACE
@@ -354,22 +308,15 @@ static Sequence *rna_Sequences_new_sound(ID *id,
int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, file, frame_start, channel);
load_data.allow_invalid_file = true;
Sequence *seq = SEQ_add_sound_strip(bmain, scene, seqbase, &load_data);
bSound *sound = BKE_sound_new_file(bmain, file);
SoundInfo info;
if (!BKE_sound_info_get(bmain, sound, &info)) {
BKE_id_free(bmain, sound);
if (seq == NULL) {
BKE_report(reports, RPT_ERROR, "Sequences.new_sound: unable to open sound file");
return NULL;
}
seq = alloc_generic_sequence(
seqbase, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->filepath);
seq->sound = sound;
seq->len = ceil((double)info.length * FPS);
SEQ_time_update_sequence_bounds(scene, seq);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
@@ -432,8 +379,7 @@ static Sequence *rna_Sequences_new_effect(ID *id,
{
Scene *scene = (Scene *)id;
Sequence *seq;
struct SeqEffectHandle sh;
int num_inputs = SEQ_effect_get_num_inputs(type);
const int num_inputs = SEQ_effect_get_num_inputs(type);
switch (num_inputs) {
case 0:
@@ -469,26 +415,14 @@ static Sequence *rna_Sequences_new_effect(ID *id,
return NULL;
}
seq = alloc_generic_sequence(seqbase, name, frame_start, channel, type, NULL);
sh = SEQ_effect_handle_get(seq);
seq->seq1 = seq1;
seq->seq2 = seq2;
seq->seq3 = seq3;
sh.init(seq);
if (!seq1) { /* effect has no deps */
seq->len = 1;
SEQ_transform_set_right_handle_frame(seq, frame_end);
}
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
SEQ_time_update_sequence(scene, seq);
SEQ_time_update_sequence_bounds(scene, seq);
SEQ_relations_invalidate_cache_composite(scene, seq);
SeqLoadData load_data;
SEQ_add_load_data_init(&load_data, name, NULL, frame_start, channel);
load_data.effect.end_frame = frame_end;
load_data.effect.type = type;
load_data.effect.seq1 = seq1;
load_data.effect.seq2 = seq2;
load_data.effect.seq3 = seq3;
seq = SEQ_add_effect_strip(scene, seqbase, &load_data);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
@@ -865,7 +799,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop, const bool metastri
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "new_movie", new_movie_func_name);
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Add a new movie sequence");
parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);