Sequencer: support for masked color balance
authorSergey Sharybin <sergey.vfx@gmail.com>
Sat, 11 Aug 2012 14:37:58 +0000 (14:37 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sat, 11 Aug 2012 14:37:58 +0000 (14:37 +0000)
This implements option which could be used to color balance only
specified area. Currently done by adding Mask input to Adjustment
effect. Affects on color balance and multiply settings.

Supporting masked saturation control is in the list, not supported
in this commit.

Also show value slider in the right of color wheel.

release/scripts/startup/bl_ui/space_sequencer.py
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesrna/intern/rna_sequencer.c

index 7778949..7b0715f 100644 (file)
@@ -423,18 +423,24 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
         return strip.type in {'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
-                              'MULTICAM'}
+                              'MULTICAM', 'ADJUSTMENT'}
 
     def draw(self, context):
         layout = self.layout
 
+        sequencer = context.scene.sequence_editor
         strip = act_strip(context)
+
         if strip.input_count > 0:
             col = layout.column()
             col.prop(strip, "input_1")
             if strip.input_count > 1:
                 col.prop(strip, "input_2")
 
+        if strip.is_supports_mask:
+            col = layout.column()
+            col.prop_search(strip, "input_mask", sequencer, "sequences")
+
         if strip.type == 'COLOR':
             layout.prop(strip, "color")
 
@@ -765,21 +771,21 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
         if strip.use_color_balance and strip.color_balance:  # TODO - need to add this somehow
             col = layout.column()
             col.label(text="Lift:")
-            col.template_color_wheel(strip.color_balance, "lift", value_slider=False, cubic=True)
+            col.template_color_wheel(strip.color_balance, "lift", value_slider=True, cubic=True)
             row = col.row()
             row.prop(strip.color_balance, "lift", text="")
             row.prop(strip.color_balance, "invert_lift", text="Inverse")
 
             col = layout.column()
             col.label(text="Gamma:")
-            col.template_color_wheel(strip.color_balance, "gamma", value_slider=False, lock_luminosity=True, cubic=True)
+            col.template_color_wheel(strip.color_balance, "gamma", value_slider=True, lock_luminosity=True, cubic=True)
             row = col.row()
             row.prop(strip.color_balance, "gamma", text="")
             row.prop(strip.color_balance, "invert_gamma", text="Inverse")
 
             col = layout.column()
             col.label(text="Gain:")
-            col.template_color_wheel(strip.color_balance, "gain", value_slider=False, lock_luminosity=True, cubic=True)
+            col.template_color_wheel(strip.color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True)
             row = col.row()
             row.prop(strip.color_balance, "gain", text="")
             row.prop(strip.color_balance, "invert_gain", text="Inverse")
index 78e65fe..fee1db9 100644 (file)
@@ -110,7 +110,8 @@ enum {
 };
 
 struct SeqEffectHandle {
-       int multithreaded;
+       short multithreaded;
+       short supports_mask;
 
        /* constructors & destructor */
        /* init is _only_ called on first creation */
@@ -150,11 +151,12 @@ struct SeqEffectHandle {
        struct ImBuf * (*execute)(SeqRenderData context, struct Sequence *seq, float cfra, float facf0, float facf1,
                                  struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3);
 
-       struct ImBuf * (*init_execution)(SeqRenderData context, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3);
+       struct ImBuf * (*init_execution)(SeqRenderData context, struct ImBuf *ibuf1, struct ImBuf *ibuf2,
+                                        struct ImBuf *ibuf3);
 
        void (*execute_slice)(SeqRenderData context, struct Sequence *seq, float cfra, float facf0, float facf1,
                              struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3,
-                              int start_line, int total_lines, struct ImBuf *out);
+                             int start_line, int total_lines, struct ImBuf *out);
 };
 
 /* ********************* prototypes *************** */
@@ -253,6 +255,7 @@ void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence
 /* extern */
 struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq);
 int BKE_sequence_effect_get_num_inputs(int seq_type);
+int BKE_sequence_effect_get_supports_mask(int seq_type);
 
 /* **********************************************************************
  * Sequencer editing functions
@@ -284,6 +287,7 @@ void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, in
 struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
 int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
 
+int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
 void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq);
 
 void BKE_sequencer_update_sound_bounds_all(struct Scene *scene);
index 911b6b0..2380596 100644 (file)
@@ -2840,6 +2840,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
        int sequence_type = seq_type;
 
        rval.multithreaded = FALSE;
+       rval.supports_mask = FALSE;
        rval.init = init_noop;
        rval.num_inputs = num_inputs_default;
        rval.load = load_noop;
@@ -2945,6 +2946,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
                        rval.execute = do_multicam;
                        break;
                case SEQ_TYPE_ADJUSTMENT:
+                       rval.supports_mask = TRUE;
                        rval.num_inputs = num_inputs_adjustment;
                        rval.early_out = early_out_adjustment;
                        rval.execute = do_adjustment;
@@ -2956,7 +2958,7 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
 
 struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq)
 {
-       struct SeqEffectHandle rval = {FALSE, NULL};
+       struct SeqEffectHandle rval = {FALSE, FALSE, NULL};
 
        if (seq->type & SEQ_TYPE_EFFECT) {
                rval = get_sequence_effect_impl(seq->type);
@@ -2971,7 +2973,7 @@ struct SeqEffectHandle BKE_sequence_get_effect(Sequence *seq)
 
 struct SeqEffectHandle BKE_sequence_get_blend(Sequence *seq)
 {
-       struct SeqEffectHandle rval = {FALSE, NULL};
+       struct SeqEffectHandle rval = {FALSE, FALSE, NULL};
 
        if (seq->blend_mode != 0) {
                rval = get_sequence_effect_impl(seq->blend_mode);
@@ -2994,3 +2996,10 @@ int BKE_sequence_effect_get_num_inputs(int seq_type)
        }
        return 0;
 }
+
+int BKE_sequence_effect_get_supports_mask(int seq_type)
+{
+       struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
+
+       return rval.supports_mask;
+}
index 4f1b324..920588d 100644 (file)
@@ -1426,12 +1426,13 @@ static void make_cb_table_float(float lift, float gain, float gamma,
        }
 }
 
-static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, int width, int height, float mul)
+static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
 {
        unsigned char cb_tab[3][256];
        int c;
        unsigned char *p = rect;
        unsigned char *e = p + width * 4 * height;
+       unsigned char *m = mask_rect;
 
        StripColorBalance cb = calc_cb(seq->strip->color_balance);
 
@@ -1440,20 +1441,32 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, int widt
        }
 
        while (p < e) {
-               p[0] = cb_tab[0][p[0]];
-               p[1] = cb_tab[1][p[1]];
-               p[2] = cb_tab[2][p[2]];
+               if (m) {
+                       float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+
+                       p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
+                       p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
+                       p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+
+                       m += 4;
+               }
+               else {
+                       p[0] = cb_tab[0][p[0]];
+                       p[1] = cb_tab[1][p[1]];
+                       p[2] = cb_tab[2][p[2]];
+               }
                
                p += 4;
        }
 }
 
-static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, int width, int height, float mul)
+static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
 {
        float cb_tab[4][256];
        int c, i;
        unsigned char *p = rect;
        unsigned char *e = p + width * 4 * height;
+       unsigned char *m = mask_rect;
        float *o;
        StripColorBalance cb;
 
@@ -1470,27 +1483,48 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
        }
 
        while (p < e) {
-               o[0] = cb_tab[0][p[0]];
-               o[1] = cb_tab[1][p[1]];
-               o[2] = cb_tab[2][p[2]];
+               if (m) {
+                       float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+
+                       p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
+                       p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
+                       p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+
+                       m += 4;
+               }
+               else {
+                       o[0] = cb_tab[0][p[0]];
+                       o[1] = cb_tab[1][p[1]];
+                       o[2] = cb_tab[2][p[2]];
+               }
+
                o[3] = cb_tab[3][p[3]];
 
                p += 4; o += 4;
        }
 }
 
-static void color_balance_float_float(Sequence *seq, float *rect_float, int width, int height, float mul)
+static void color_balance_float_float(Sequence *seq, float *rect_float, float *mask_rect_float, int width, int height, float mul)
 {
        float *p = rect_float;
        float *e = rect_float + width * 4 * height;
+       float *m = mask_rect_float;
        StripColorBalance cb = calc_cb(seq->strip->color_balance);
 
        while (p < e) {
                int c;
                for (c = 0; c < 3; c++) {
-                       p[c] = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
+                       float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
+
+                       if (m)
+                               p[c] = p[c] * (1.0f - m[c]) + t * m[c];
+                       else
+                               p[c] = t;
                }
+
                p += 4;
+               if (m)
+                       m += 4;
        }
 }
 
@@ -1498,6 +1532,7 @@ typedef struct ColorBalanceInitData {
        Sequence *seq;
        ImBuf *ibuf;
        float mul;
+       ImBuf *mask;
 } ColorBalanceInitData;
 
 typedef struct ColorBalanceThread {
@@ -1506,8 +1541,8 @@ typedef struct ColorBalanceThread {
 
        int width, height;
 
-       unsigned char *rect;
-       float *rect_float;
+       unsigned char *rect, *mask_rect;
+       float *rect_float, *mask_rect_float;
 } ColorBalanceThread;
 
 static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1515,6 +1550,7 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
        ColorBalanceThread *handle = (ColorBalanceThread *) handle_v;
        ColorBalanceInitData *init_data = (ColorBalanceInitData *) init_data_v;
        ImBuf *ibuf = init_data->ibuf;
+       ImBuf *mask = init_data->mask;
 
        int offset = 4 * start_line * ibuf->x;
 
@@ -1530,6 +1566,18 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
 
        if (ibuf->rect_float)
                handle->rect_float = ibuf->rect_float + offset;
+
+       if (mask) {
+               if (mask->rect)
+                       handle->mask_rect = (unsigned char *) mask->rect + offset;
+
+               if (mask->rect_float)
+                       handle->mask_rect_float = mask->rect_float + offset;
+       }
+       else {
+               handle->mask_rect = NULL;
+               handle->mask_rect_float = NULL;
+       }
 }
 
 static void *color_balance_do_thread(void *thread_data_v)
@@ -1538,53 +1586,60 @@ static void *color_balance_do_thread(void *thread_data_v)
        Sequence *seq = thread_data->seq;
        int width = thread_data->width, height = thread_data->height;
        unsigned char *rect = thread_data->rect;
+       unsigned char *mask_rect = thread_data->mask_rect;
        float *rect_float = thread_data->rect_float;
+       float *mask_rect_float = thread_data->mask_rect_float;
        float mul = thread_data->mul;
 
        if (rect_float) {
-               color_balance_float_float(seq, rect_float, width, height, mul);
+               color_balance_float_float(seq, rect_float, mask_rect_float, width, height, mul);
        }
        else if (seq->flag & SEQ_MAKE_FLOAT) {
-               color_balance_byte_float(seq, rect, rect_float, width, height, mul);
+               color_balance_byte_float(seq, rect, rect_float, mask_rect, width, height, mul);
        }
        else {
-               color_balance_byte_byte(seq, rect, width, height, mul);
+               color_balance_byte_byte(seq, rect, mask_rect, width, height, mul);
        }
 
        return NULL;
 }
 
-static void color_balance(Sequence *seq, ImBuf *ibuf, float mul)
+static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
 {
+       ColorBalanceInitData init_data;
+
        if (!ibuf->rect_float && seq->flag & SEQ_MAKE_FLOAT)
                imb_addrectfloatImBuf(ibuf);
 
-       if (BLI_thread_is_main()) {
-               /* color balance could have been called from prefetching job which
-                * is already multithreaded, so doing threading here makes no sense
-                */
-               ColorBalanceInitData init_data;
-
-               init_data.seq = seq;
-               init_data.ibuf = ibuf;
-               init_data.mul = mul;
-
-               IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
-                                        color_balance_init_handle, color_balance_do_thread);
+       init_data.seq = seq;
+       init_data.ibuf = ibuf;
+       init_data.mul = mul;
+       init_data.mask = NULL;
+
+       if (seq->mask_sequence) {
+               if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
+                       ImBuf *mask = seq_render_strip(context, seq->mask_sequence, cfra);
+
+                       if (mask) {
+                               if (ibuf->rect_float) {
+                                       if (!mask->rect_float)
+                                               IMB_float_from_rect(mask);
+                               }
+                               else {
+                                       if (!mask->rect)
+                                               IMB_rect_from_float(mask);
+                               }
 
+                               init_data.mask = mask;
+                       }
+               }
        }
-       else {
-               ColorBalanceThread handle;
 
-               handle.seq = seq;
-               handle.mul = mul;
-               handle.width = ibuf->x;
-               handle.height = ibuf->y;
-               handle.rect = (unsigned char *)ibuf->rect;
-               handle.rect_float = ibuf->rect_float;
+       IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
+                                 color_balance_init_handle, color_balance_do_thread);
 
-               color_balance_do_thread(&handle);
-       }
+       if (init_data.mask)
+               IMB_freeImBuf(init_data.mask);
 }
 
 /*
@@ -1632,7 +1687,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
        return FALSE;
 }
 
-static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf *ibuf,
+static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, ImBuf *ibuf,
                                int is_proxy_image, int is_preprocessed)
 {
        float mul;
@@ -1727,7 +1782,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float UNUSE
        }
 
        if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
-               color_balance(seq, ibuf, mul);
+               color_balance(context, seq, ibuf, mul, cfra);
                mul = 1.0;
        }
 
@@ -2784,11 +2839,34 @@ static void free_anim_seq(Sequence *seq)
        }
 }
 
+/* check whether sequence cur depends on seq */
+int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
+{
+       /* sequences are not intersecting in time, assume no dependency exists between them */
+       if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp)
+               return FALSE;
+
+       /* checking sequence is below reference one, not dependent on it */
+       if (cur->machine < seq->machine)
+               return FALSE;
+
+       /* sequence is not blending with lower machines, no dependency here occurs
+        * check for non-effects only since effect could use lower machines as input
+        */
+       if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
+                   ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
+                (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
+       {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
 {
        Editing *ed = scene->ed;
        Sequence *cur;
-       int left = seq->startdisp, right = seq->enddisp;
 
        /* invalidate cache for current sequence */
        BKE_sequencer_cache_cleanup_sequence(seq);
@@ -2796,27 +2874,11 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
        /* invalidate cache for all dependent sequences */
        SEQ_BEGIN (ed, cur)
        {
-               int cur_left = cur->startdisp, cur_right = cur->enddisp;
-
                if (cur == seq)
                        continue;
 
-               /* sequence is outside of changed one, shouldn't be invalidated */
-               if (cur_right < left || cur_left > right)
-                       continue;
-
-               /* sequence is below changed one, not dependent on it */
-               if (cur->machine < seq->machine)
-                       continue;
-
-               /* sequence is not blending with lower machines, no need to invalidate */
-               if ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
-                   (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f))
-               {
-                       continue;
-               }
-
-               BKE_sequencer_cache_cleanup_sequence(cur);
+               if (BKE_sequence_check_depend(seq, cur))
+                       BKE_sequencer_cache_cleanup_sequence(cur);
        }
        SEQ_END
 }
index 1f3662e..c235034 100644 (file)
@@ -4972,6 +4972,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        seq->seq1= newdataadr(fd, seq->seq1);
                        seq->seq2= newdataadr(fd, seq->seq2);
                        seq->seq3= newdataadr(fd, seq->seq3);
+                       seq->mask_sequence= newdataadr(fd, seq->mask_sequence);
                        /* a patch: after introduction of effects with 3 input strips */
                        if (seq->seq3 == NULL) seq->seq3 = seq->seq2;
                        
index 161c448..9731854 100644 (file)
@@ -140,6 +140,9 @@ typedef struct Sequence {
        /* pointers for effects: */
        struct Sequence *seq1, *seq2, *seq3;
 
+       /* maks input for effects */
+       struct Sequence *mask_sequence;
+
        ListBase seqbase;       /* list of strips for metastrips */
 
        struct bSound *sound;   /* the linked "bSound" object */
index 8c0c87e..06742f5 100644 (file)
@@ -55,6 +55,7 @@ typedef struct EffectInfo {
        const char *ui_desc;
        void (*func)(StructRNA *);
        int inputs;
+       int supports_mask;
 } EffectInfo;
 
 #ifdef RNA_RUNTIME
@@ -590,6 +591,13 @@ static int rna_Sequence_input_count_get(PointerRNA *ptr)
        return BKE_sequence_effect_get_num_inputs(seq->type);
 }
 
+static int rna_Sequence_supports_mask_get(PointerRNA *ptr)
+{
+       Sequence *seq = (Sequence *)(ptr->data);
+
+       return BKE_sequence_effect_get_supports_mask(seq->type);
+}
+
 #if 0
 static void rna_SoundSequence_filename_set(PointerRNA *ptr, const char *value)
 {
@@ -616,6 +624,20 @@ static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *p
        }
 }
 
+static int rna_Sequence_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
+{
+       Sequence *seq = (Sequence *) ptr->data;
+       Sequence *cur = (Sequence *) value.data;
+
+       if (seq == cur)
+               return FALSE;
+
+       if (BKE_sequence_check_depend(seq, cur))
+               return FALSE;
+
+       return TRUE;
+}
+
 static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
 {
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -1412,7 +1434,7 @@ static void rna_def_input(StructRNA *srna)
        RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
 }
 
-static void rna_def_effect_inputs(StructRNA *srna, int count)
+static void rna_def_effect_inputs(StructRNA *srna, int count, int supports_mask)
 {
        PropertyRNA *prop;
 
@@ -1420,6 +1442,10 @@ static void rna_def_effect_inputs(StructRNA *srna, int count)
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_int_funcs(prop, "rna_Sequence_input_count_get", NULL, NULL);
 
+       prop = RNA_def_property(srna, "is_supports_mask", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_int_funcs(prop, "rna_Sequence_supports_mask_get", NULL, NULL);
+
        if (count >= 1) {
                prop = RNA_def_property(srna, "input_1",  PROP_POINTER, PROP_NONE);
                RNA_def_property_pointer_sdna(prop, NULL, "seq1");
@@ -1442,6 +1468,15 @@ static void rna_def_effect_inputs(StructRNA *srna, int count)
                RNA_def_property_ui_text(prop, "Input 3", "Third input for the effect strip");
        }
        */
+
+       if (supports_mask) {
+               prop = RNA_def_property(srna, "input_mask",  PROP_POINTER, PROP_NONE);
+               RNA_def_property_pointer_sdna(prop, NULL, "mask_sequence");
+               RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Sequence_otherSequence_poll");
+               RNA_def_property_flag(prop, PROP_EDITABLE);
+               RNA_def_property_ui_text(prop, "Mask", "Mask input for the effect strip");
+               RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       }
 }
 
 static void rna_def_image(BlenderRNA *brna)
@@ -1884,50 +1919,50 @@ static void rna_def_speed_control(StructRNA *srna)
 static EffectInfo def_effects[] = {
        {"AddSequence", "Add Sequence",
         "Add Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"AdjustmentSequence", "Adjustment Layer Sequence",
         "Sequence strip to perform filter adjustments to layers below",
-        rna_def_input, 0},
+        rna_def_input, 0, TRUE},
        {"AlphaOverSequence", "Alpha Over Sequence",
         "Alpha Over Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"AlphaUnderSequence", "Alpha Under Sequence",
         "Alpha Under Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"ColorSequence", "Color Sequence",
         "Sequence strip creating an image filled with a single color",
-        rna_def_solid_color, 0},
+        rna_def_solid_color, 0, FALSE},
        {"CrossSequence", "Cross Sequence",
         "Cross Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"GammaCrossSequence", "Gamma Cross Sequence",
         "Gamma Cross Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"GlowSequence", "Glow Sequence",
         "Sequence strip creating a glow effect",
-        rna_def_glow, 1},
+        rna_def_glow, 1, FALSE},
        {"MulticamSequence", "Multicam Select Sequence",
         "Sequence strip to perform multicam editing",
-        rna_def_multicam, 0},
+        rna_def_multicam, 0, FALSE},
        {"MultiplySequence", "Multiply Sequence",
         "Multiply Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"OverDropSequence", "Over Drop Sequence",
         "Over Drop Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"SpeedControlSequence", "SpeedControl Sequence",
         "Sequence strip to control the speed of other strips",
-        rna_def_speed_control, 1},
+        rna_def_speed_control, 1, FALSE},
        {"SubtractSequence", "Subtract Sequence",
         "Subtract Sequence",
-        NULL, 2},
+        NULL, 2, FALSE},
        {"TransformSequence", "Transform Sequence",
         "Sequence strip applying affine transformations to other strips",
-        rna_def_transform, 1},
+        rna_def_transform, 1, FALSE},
        {"WipeSequence", "Wipe Sequence",
         "Sequence strip creating a wipe transition",
-        rna_def_wipe, 1},
-       {"", "", "", NULL, 0}
+        rna_def_wipe, 1, FALSE},
+       {"", "", "", NULL, 0, FALSE}
 };
 
 static void rna_def_effects(BlenderRNA *brna)
@@ -1940,7 +1975,7 @@ static void rna_def_effects(BlenderRNA *brna)
                RNA_def_struct_ui_text(srna, effect->ui_name, effect->ui_desc);
                RNA_def_struct_sdna(srna, "Sequence");
 
-               rna_def_effect_inputs(srna, effect->inputs);
+               rna_def_effect_inputs(srna, effect->inputs, effect->supports_mask);
 
                if (effect->func)
                        effect->func(srna);