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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user