Merging r50149 through r50156 from trunk into soc-2011-tomato
[blender.git] / source / blender / makesrna / intern / rna_sequencer.c
index 9082bb42be54b9a77ba1a022af729425edb759b4..bdee89308cfa4fbd06b2b69d62e42444002700b1 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "RNA_access.h"
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
 
 #include "rna_internal.h"
 
@@ -55,16 +56,35 @@ typedef struct EffectInfo {
        const char *ui_desc;
        void (*func)(StructRNA *);
        int inputs;
+       int supports_mask;
 } EffectInfo;
 
+EnumPropertyItem sequence_modifier_type_items[] = {
+       {seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
+       {seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
+       {seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
 #ifdef RNA_RUNTIME
 
-/* build a temp referene to the parent */
+#include "BKE_report.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+typedef struct SequenceSearchData {
+       Sequence *seq;
+       void *data;
+       SequenceModifierData *smd;
+} SequenceSearchData;
+
+/* build a temp reference to the parent */
 static void meta_tmp_ref(Sequence *seq_par, Sequence *seq)
 {
        for (; seq; seq = seq->next) {
                seq->tmp = seq_par;
-               if (seq->type == SEQ_META) {
+               if (seq->type == SEQ_TYPE_META) {
                        meta_tmp_ref(seq, seq->seqbase.first);
                }
        }
@@ -126,11 +146,11 @@ static void rna_SequenceEditor_elements_begin(CollectionPropertyIterator *iter,
 static void rna_Sequence_frame_change_update(Scene *scene, Sequence *seq)
 {
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       ListBase *seqbase = seq_seqbase(&ed->seqbase, seq);
-       calc_sequence_disp(scene, seq);
+       ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
+       BKE_sequence_calc_disp(scene, seq);
 
-       if (seq_test_overlap(seqbase, seq)) {
-               shuffle_seq(seqbase, seq, scene); /* XXX - BROKEN!, uses context seqbasep */
+       if (BKE_sequence_test_overlap(seqbase, seq)) {
+               BKE_sequence_base_shuffle(seqbase, seq, scene); /* XXX - BROKEN!, uses context seqbasep */
        }
        BKE_sequencer_sort(scene);
 }
@@ -140,7 +160,7 @@ static void rna_Sequence_start_frame_set(PointerRNA *ptr, int value)
        Sequence *seq = (Sequence *)ptr->data;
        Scene *scene = (Scene *)ptr->id.data;
        
-       seq_translate(scene, seq, value - seq->start);
+       BKE_sequence_translate(scene, seq, value - seq->start);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
@@ -149,8 +169,8 @@ static void rna_Sequence_start_frame_final_set(PointerRNA *ptr, int value)
        Sequence *seq = (Sequence *)ptr->data;
        Scene *scene = (Scene *)ptr->id.data;
 
-       seq_tx_set_final_left(seq, value);
-       seq_single_fix(seq);
+       BKE_sequence_tx_set_final_left(seq, value);
+       BKE_sequence_single_fix(seq);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
@@ -159,8 +179,8 @@ static void rna_Sequence_end_frame_final_set(PointerRNA *ptr, int value)
        Sequence *seq = (Sequence *)ptr->data;
        Scene *scene = (Scene *)ptr->id.data;
 
-       seq_tx_set_final_right(seq, value);
-       seq_single_fix(seq);
+       BKE_sequence_tx_set_final_right(seq, value);
+       BKE_sequence_single_fix(seq);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
@@ -171,7 +191,7 @@ static void rna_Sequence_anim_startofs_final_set(PointerRNA *ptr, int value)
 
        seq->anim_startofs = MIN2(value, seq->len + seq->anim_startofs);
 
-       reload_sequence_new_file(scene, seq, FALSE);
+       BKE_sequence_reload_new_file(scene, seq, FALSE);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
@@ -182,7 +202,7 @@ static void rna_Sequence_anim_endofs_final_set(PointerRNA *ptr, int value)
 
        seq->anim_endofs = MIN2(value, seq->len + seq->anim_endofs);
 
-       reload_sequence_new_file(scene, seq, FALSE);
+       BKE_sequence_reload_new_file(scene, seq, FALSE);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
@@ -191,21 +211,21 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
        Sequence *seq = (Sequence *)ptr->data;
        Scene *scene = (Scene *)ptr->id.data;
        
-       seq_tx_set_final_right(seq, seq->start + value);
+       BKE_sequence_tx_set_final_right(seq, seq->start + value);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
 static int rna_Sequence_frame_length_get(PointerRNA *ptr)
 {
        Sequence *seq = (Sequence *)ptr->data;
-       return seq_tx_get_final_right(seq, 0) - seq_tx_get_final_left(seq, 0);
+       return BKE_sequence_tx_get_final_right(seq, 0) - BKE_sequence_tx_get_final_left(seq, 0);
 }
 
 static int rna_Sequence_frame_editable(PointerRNA *ptr)
 {
        Sequence *seq = (Sequence *)ptr->data;
        /* Effect sequences' start frame and length must be readonly! */
-       return (get_sequence_effect_num_inputs(seq->type)) ? 0 : PROP_EDITABLE;
+       return (BKE_sequence_effect_get_num_inputs(seq->type)) ? 0 : PROP_EDITABLE;
 }
 
 static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
@@ -213,12 +233,12 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
        Sequence *seq = (Sequence *)ptr->data;
        Scene *scene = (Scene *)ptr->id.data;
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       ListBase *seqbase = seq_seqbase(&ed->seqbase, seq);
+       ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
 
        seq->machine = value;
        
-       if (seq_test_overlap(seqbase, seq) ) {
-               shuffle_seq(seqbase, seq, scene);  /* XXX - BROKEN!, uses context seqbasep */
+       if (BKE_sequence_test_overlap(seqbase, seq) ) {
+               BKE_sequence_base_shuffle(seqbase, seq, scene);  /* XXX - BROKEN!, uses context seqbasep */
        }
        BKE_sequencer_sort(scene);
 }
@@ -292,28 +312,33 @@ static void rna_Sequence_use_crop_set(PointerRNA *ptr, int value)
 
 static int transform_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *transform; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->transform == data->transform) {
+       if (seq->strip && seq->strip->transform == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static char *rna_SequenceTransform_path(PointerRNA *ptr)
+static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transform)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *transform; } data;
        data.seq = NULL;
-       data.transform = ptr->data;
+       data.data = transform;
 
        /* irritating we need to search for our sequence! */
-       seqbase_recursive_apply(&ed->seqbase, transform_seq_cmp_cb, &data);
-       seq = data.seq;
+       BKE_sequencer_base_recursive_apply(&ed->seqbase, transform_seq_cmp_cb, &data);
+
+       return data.seq;
+}
+
+static char *rna_SequenceTransform_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_transform(ed, ptr->data);
 
        if (seq && seq->name + 2)
                return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform", seq->name + 2);
@@ -321,30 +346,44 @@ static char *rna_SequenceTransform_path(PointerRNA *ptr)
                return BLI_strdup("");
 }
 
+static void rna_SequenceTransform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_transform(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
+
 static int crop_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *crop; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->crop == data->crop) {
+       if (seq->strip && seq->strip->crop == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static char *rna_SequenceCrop_path(PointerRNA *ptr)
+static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *crop; } data;
        data.seq = NULL;
-       data.crop = ptr->data;
+       data.data = crop;
 
        /* irritating we need to search for our sequence! */
-       seqbase_recursive_apply(&ed->seqbase, crop_seq_cmp_cb, &data);
-       seq = data.seq;
+       BKE_sequencer_base_recursive_apply(&ed->seqbase, crop_seq_cmp_cb, &data);
+
+       return data.seq;
+}
+
+static char *rna_SequenceCrop_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_crop(ed, ptr->data);
 
        if (seq && seq->name + 2)
                return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop", seq->name + 2);
@@ -352,6 +391,14 @@ static char *rna_SequenceCrop_path(PointerRNA *ptr)
                return BLI_strdup("");
 }
 
+static void rna_SequenceCrop_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_crop(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
 
 /* name functions that ignore the first two characters */
 static void rna_Sequence_name_get(PointerRNA *ptr, char *value)
@@ -380,7 +427,7 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value)
        BLI_strncpy_utf8(seq->name + 2, value, sizeof(seq->name) - 2);
        
        /* make sure the name is unique */
-       seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
+       BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq);
        
        /* fix all the animation data which may link to this */
 
@@ -396,47 +443,49 @@ static StructRNA *rna_Sequence_refine(struct PointerRNA *ptr)
        Sequence *seq = (Sequence *)ptr->data;
 
        switch (seq->type) {
-               case SEQ_IMAGE:
+               case SEQ_TYPE_IMAGE:
                        return &RNA_ImageSequence;
-               case SEQ_META:
+               case SEQ_TYPE_META:
                        return &RNA_MetaSequence;
-               case SEQ_SCENE:
+               case SEQ_TYPE_SCENE:
                        return &RNA_SceneSequence;
-               case SEQ_MOVIE:
+               case SEQ_TYPE_MOVIE:
                        return &RNA_MovieSequence;
-               case SEQ_MOVIECLIP:
+               case SEQ_TYPE_MOVIECLIP:
                        return &RNA_MovieClipSequence;
-               case SEQ_SOUND:
+               case SEQ_TYPE_MASK:
+                       return &RNA_MaskSequence;
+               case SEQ_TYPE_SOUND_RAM:
                        return &RNA_SoundSequence;
-               case SEQ_CROSS:
+               case SEQ_TYPE_CROSS:
                        return &RNA_CrossSequence;
-               case SEQ_ADD:
+               case SEQ_TYPE_ADD:
                        return &RNA_AddSequence;
-               case SEQ_SUB:
+               case SEQ_TYPE_SUB:
                        return &RNA_SubtractSequence;
-               case SEQ_ALPHAOVER:
+               case SEQ_TYPE_ALPHAOVER:
                        return &RNA_AlphaOverSequence;
-               case SEQ_ALPHAUNDER:
+               case SEQ_TYPE_ALPHAUNDER:
                        return &RNA_AlphaUnderSequence;
-               case SEQ_GAMCROSS:
+               case SEQ_TYPE_GAMCROSS:
                        return &RNA_GammaCrossSequence;
-               case SEQ_MUL:
+               case SEQ_TYPE_MUL:
                        return &RNA_MultiplySequence;
-               case SEQ_OVERDROP:
+               case SEQ_TYPE_OVERDROP:
                        return &RNA_OverDropSequence;
-               case SEQ_MULTICAM:
+               case SEQ_TYPE_MULTICAM:
                        return &RNA_MulticamSequence;
-               case SEQ_ADJUSTMENT:
+               case SEQ_TYPE_ADJUSTMENT:
                        return &RNA_AdjustmentSequence;
-               case SEQ_WIPE:
+               case SEQ_TYPE_WIPE:
                        return &RNA_WipeSequence;
-               case SEQ_GLOW:
+               case SEQ_TYPE_GLOW:
                        return &RNA_GlowSequence;
-               case SEQ_TRANSFORM:
+               case SEQ_TYPE_TRANSFORM:
                        return &RNA_TransformSequence;
-               case SEQ_COLOR:
+               case SEQ_TYPE_COLOR:
                        return &RNA_ColorSequence;
-               case SEQ_SPEED:
+               case SEQ_TYPE_SPEED:
                        return &RNA_SpeedControlSequence;
                default:
                        return &RNA_Sequence;
@@ -469,7 +518,7 @@ static void rna_Sequence_filepath_set(PointerRNA *ptr, const char *value)
 {
        Sequence *seq = (Sequence *)(ptr->data);
 
-       if (seq->type == SEQ_SOUND && seq->sound) {
+       if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound) {
                /* for sound strips we need to update the sound as well.
                 * arguably, this could load in a new sound rather than modify an existing one.
                 * but while using the sequencer its most likely your not using the sound in the game engine too.
@@ -555,7 +604,14 @@ static int rna_Sequence_input_count_get(PointerRNA *ptr)
 {
        Sequence *seq = (Sequence *)(ptr->data);
 
-       return get_sequence_effect_num_inputs(seq->type);
+       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
@@ -573,68 +629,102 @@ static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value)
 }
 #endif
 
-static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Sequence_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
+       Scene *scene = (Scene *) ptr->id.data;
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
 
-       if (ed)
-               free_imbuf_seq(scene, &ed->seqbase, FALSE, TRUE);
+       if (ed) {
+               Sequence *seq = (Sequence *) ptr->data;
+
+               BKE_sequence_invalidate_cache(scene, seq);
+       }
 }
 
-static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+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 *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
 
-       free_imbuf_seq(scene, &ed->seqbase, FALSE, FALSE);
+       BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
 
        if (RNA_struct_is_a(ptr->type, &RNA_SoundSequence))
-               seq_update_sound_bounds(scene, ptr->data);
+               BKE_sequencer_update_sound_bounds(scene, ptr->data);
 }
 
-static void rna_Sequence_mute_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Sequence_mute_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
+       Scene *scene = (Scene *) ptr->id.data;
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
 
-       seq_update_muting(ed);
+       BKE_sequencer_update_muting(ed);
        rna_Sequence_update(bmain, scene, ptr);
 }
 
-static void rna_Sequence_filepath_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
+       Scene *scene = (Scene *) ptr->id.data;
        Sequence *seq = (Sequence *)(ptr->data);
-       reload_sequence_new_file(scene, seq, TRUE);
-       calc_sequence(scene, seq);
+       BKE_sequence_reload_new_file(scene, seq, TRUE);
+       BKE_sequence_calc(scene, seq);
        rna_Sequence_update(bmain, scene, ptr);
 }
 
 static int seqproxy_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *seq_proxy; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->proxy == data->seq_proxy) {
+       if (seq->strip && seq->strip->proxy == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static void rna_Sequence_tcindex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
 {
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
-
-       struct { Sequence *seq; void *seq_proxy; } data;
+       SequenceSearchData data;
 
        data.seq = NULL;
-       data.seq_proxy = ptr->data;
+       data.data = proxy;
 
-       seqbase_recursive_apply(&ed->seqbase, seqproxy_seq_cmp_cb, &data);
-       seq = data.seq;
+       BKE_sequencer_base_recursive_apply(&ed->seqbase, seqproxy_seq_cmp_cb, &data);
+       return data.seq;
+}
 
-       reload_sequence_new_file(scene, seq, FALSE);
+static void rna_Sequence_tcindex_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
+
+       BKE_sequence_reload_new_file(scene, seq, FALSE);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
+static void rna_SequenceProxy_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
+
 /* do_versions? */
 static float rna_Sequence_opacity_get(PointerRNA *ptr)
 {
@@ -648,37 +738,85 @@ static void rna_Sequence_opacity_set(PointerRNA *ptr, float value)
        seq->blend_opacity = value * 100.0f;
 }
 
-
 static int colbalance_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *color_balance; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->color_balance == data->color_balance) {
+       if (seq->strip && seq->strip->color_balance == data->data) {
                data->seq = seq;
+               data->smd = NULL;
                return -1; /* done so bail out */
        }
+
+       if (seq->modifiers.first) {
+               SequenceModifierData *smd = seq->modifiers.first;
+
+               for (smd = seq->modifiers.first; smd; smd = smd->next) {
+                       if (smd->type == seqModifierType_ColorBalance) {
+                               ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
+
+                               if (&cbmd->color_balance == data->data) {
+                                       data->seq = seq;
+                                       data->smd = smd;
+                                       return -1; /* done so bail out */
+                               }
+                       }
+               }
+       }
+
        return 1;
 }
-static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
+
+static Sequence *sequence_get_by_colorbalance(Editing *ed, StripColorBalance *cb, SequenceModifierData **smd_r)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *color_balance; } data;
        data.seq = NULL;
-       data.color_balance = ptr->data;
+       data.smd = NULL;
+       data.data = cb;
 
        /* irritating we need to search for our sequence! */
-       seqbase_recursive_apply(&ed->seqbase, colbalance_seq_cmp_cb, &data);
-       seq = data.seq;
+       BKE_sequencer_base_recursive_apply(&ed->seqbase, colbalance_seq_cmp_cb, &data);
 
-       if (seq && seq->name + 2)
-               return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].color_balance", seq->name + 2);
+       *smd_r = data.smd;
+
+       return data.seq;
+}
+
+static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       SequenceModifierData *smd;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data, &smd);
+
+       if (seq && seq->name + 2) {
+               if (!smd) {
+                       /* path to old filter color balance */
+                       return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].color_balance", seq->name + 2);
+               }
+               else {
+                       /* path to modifier */
+                       return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].modifiers[\"%s\"].color_balance", seq->name + 2, smd->name);
+               }
+       }
        else
                return BLI_strdup("");
 }
 
+static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       SequenceModifierData *smd;
+       Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data, &smd);
+
+       if (smd == NULL)
+               BKE_sequence_invalidate_cache(scene, seq);
+       else
+               BKE_sequence_invalidate_cache_for_modifier(scene, seq);
+}
+
 static void rna_SequenceEditor_overlay_lock_set(PointerRNA *ptr, int value)
 {
        Scene *scene = ptr->id.data;
@@ -744,6 +882,159 @@ static float rna_WipeSequence_angle_get(PointerRNA *ptr)
        return DEG2RADF(((WipeVars *)seq->effectdata)->angle);
 }
 
+static int modifier_seq_cmp_cb(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 1;
+}
+
+static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd)
+{
+       SequenceSearchData data;
+
+       data.seq = NULL;
+       data.data = smd;
+
+       /* irritating we need to search for our sequence! */
+       BKE_sequencer_base_recursive_apply(&ed->seqbase, modifier_seq_cmp_cb, &data);
+
+       return data.seq;
+}
+
+static StructRNA *rna_SequenceModifier_refine(struct PointerRNA *ptr)
+{
+       SequenceModifierData *smd = (SequenceModifierData *) ptr->data;
+
+       switch (smd->type) {
+               case seqModifierType_ColorBalance:
+                       return &RNA_ColorBalanceModifier;
+               case seqModifierType_Curves:
+                       return &RNA_CurvesModifier;
+               case seqModifierType_HueCorrect:
+                       return &RNA_HueCorrectModifier;
+               default:
+                       return &RNA_SequenceModifier;
+       }
+}
+
+static char *rna_SequenceModifier_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       SequenceModifierData *smd = ptr->data;
+       Sequence *seq = sequence_get_by_modifier(ed, smd);
+
+       if (seq && seq->name + 2)
+               return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].modifiers[\"%s\"]", seq->name + 2, smd->name);
+       else
+               return BLI_strdup("");
+}
+
+static void rna_SequenceModifier_name_set(PointerRNA *ptr, const char *value)
+{
+       SequenceModifierData *smd = ptr->data;
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_modifier(ed, smd);
+       AnimData *adt;
+       char oldname[sizeof(smd->name)];
+
+       /* make a copy of the old name first */
+       BLI_strncpy(oldname, smd->name, sizeof(smd->name));
+
+       /* copy the new name into the name slot */
+       BLI_strncpy_utf8(smd->name, value, sizeof(smd->name));
+
+       /* make sure the name is truly unique */
+       BKE_sequence_modifier_unique_name(seq, smd);
+
+       /* fix all the animation data which may link to this */
+       adt = BKE_animdata_from_id(&scene->id);
+       if (adt) {
+               char path[1024];
+
+               BLI_snprintf(path, sizeof(path), "sequence_editor.sequences_all[\"%s\"].modifiers", seq->name + 2);
+               BKE_animdata_fix_paths_rename(&scene->id, adt, NULL, path, oldname, smd->name, 0, 0, 1);
+       }
+}
+
+static void rna_SequenceModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+       /* strip from other scenes could be modified, so using active scene is not reliable */
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache_for_modifier(scene, seq);
+}
+
+static int rna_SequenceModifier_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
+{
+       Scene *scene = (Scene *) ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
+       Sequence *cur = (Sequence *) value.data;
+
+       if (seq == cur)
+               return FALSE;
+
+       if (BKE_sequence_check_depend(seq, cur))
+               return FALSE;
+
+       return TRUE;
+}
+
+static SequenceModifierData *rna_Sequence_modifier_new(Sequence *seq, bContext *C, ReportList *reports, const char *name, int type)
+{
+       if (!BKE_sequence_supports_modifiers(seq)) {
+               BKE_report(reports, RPT_ERROR, "Sequence type does not support modifiers");
+
+               return NULL;
+       }
+       else {
+               Scene *scene = CTX_data_scene(C);
+               SequenceModifierData *smd;
+
+               smd = BKE_sequence_modifier_new(seq, name, type);
+
+               BKE_sequence_invalidate_cache_for_modifier(scene, seq);
+
+               WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
+
+               return smd;
+       }
+}
+
+static void rna_Sequence_modifier_remove(Sequence *seq, bContext *C, ReportList *reports, SequenceModifierData *smd)
+{
+       Scene *scene = CTX_data_scene(C);
+
+       if (BKE_sequence_modifier_remove(seq, smd)) {
+               BKE_sequence_invalidate_cache_for_modifier(scene, seq);
+
+               WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
+       }
+       else {
+               BKE_report(reports, RPT_ERROR, "Modifier was not found in the stack");
+       }
+}
+
+static void rna_Sequence_modifier_clear(Sequence *seq, bContext *C)
+{
+       Scene *scene = CTX_data_scene(C);
+
+       BKE_sequence_modifier_clear(seq);
+
+       BKE_sequence_invalidate_cache_for_modifier(scene, seq);
+
+       WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
+}
 
 #else
 
@@ -785,25 +1076,25 @@ static void rna_def_strip_crop(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "top");
        RNA_def_property_ui_text(prop, "Top", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
        
        prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "bottom");
        RNA_def_property_ui_text(prop, "Bottom", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
        
        prop = RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "left");
        RNA_def_property_ui_text(prop, "Left", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
 
        prop = RNA_def_property(srna, "max_x", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "right");
        RNA_def_property_ui_text(prop, "Right", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
 
        RNA_def_struct_path_func(srna, "rna_SequenceCrop_path");
 }
@@ -821,13 +1112,13 @@ static void rna_def_strip_transform(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "xofs");
        RNA_def_property_ui_text(prop, "Offset X", "");
        RNA_def_property_ui_range(prop, -4096, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
 
        prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "yofs");
        RNA_def_property_ui_text(prop, "Offset Y", "");
        RNA_def_property_ui_range(prop, -4096, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
 
        RNA_def_struct_path_func(srna, "rna_SequenceTransform_path");
 
@@ -860,14 +1151,14 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
        prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
        RNA_def_property_string_sdna(prop, NULL, "dir");
        RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
        
        prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_ui_text(prop, "Path", "Location of custom proxy file");
        RNA_def_property_string_funcs(prop, "rna_Sequence_proxy_filepath_get", "rna_Sequence_proxy_filepath_length",
                                      "rna_Sequence_proxy_filepath_set");
 
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
 
        prop = RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", SEQ_PROXY_IMAGE_SIZE_25);
@@ -910,101 +1201,153 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
 
 }
 
-static void rna_def_strip_color_balance(BlenderRNA *brna)
+static void rna_def_color_balance(BlenderRNA *brna)
 {
        StructRNA *srna;
        PropertyRNA *prop;
 
-       srna = RNA_def_struct(brna, "SequenceColorBalance", NULL);
-       RNA_def_struct_ui_text(srna, "Sequence Color Balance", "Color balance parameters for a sequence strip");
+       srna = RNA_def_struct(brna, "SequenceColorBalanceData", NULL);
+       RNA_def_struct_ui_text(srna, "Sequence Color Balance Data", "Color balance parameters for a sequence strip and it's modifiers");
        RNA_def_struct_sdna(srna, "StripColorBalance");
 
        prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Lift", "Color balance lift (shadows)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-       
+       RNA_def_property_float_default(prop, 1.0f);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
+
        prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Gamma", "Color balance gamma (midtones)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-       
+       RNA_def_property_float_default(prop, 1.0f);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
+
        prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Gain", "Color balance gain (highlights)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-       
+       RNA_def_property_float_default(prop, 1.0f);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
+
        prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN);
        RNA_def_property_ui_text(prop, "Inverse Gain", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA);
        RNA_def_property_ui_text(prop, "Inverse Gamma", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        prop = RNA_def_property(srna, "invert_lift", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_LIFT);
        RNA_def_property_ui_text(prop, "Inverse Lift", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
-       RNA_def_struct_path_func(srna, "rna_SequenceColorBalance_path");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        /* not yet used */
 #if 0
        prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Exposure", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-       
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_ColorBabalnce_update");
+
        prop = RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Saturation", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_ColorBabalnce_update");
 #endif
+
+       RNA_def_struct_path_func(srna, "rna_SequenceColorBalance_path");
+}
+
+static void rna_def_strip_color_balance(BlenderRNA *brna)
+{
+       StructRNA *srna;
+
+       srna = RNA_def_struct(brna, "SequenceColorBalance", "SequenceColorBalanceData");
+       RNA_def_struct_ui_text(srna, "Sequence Color Balance", "Color balance parameters for a sequence strip");
+       RNA_def_struct_sdna(srna, "StripColorBalance");
 }
 
 EnumPropertyItem blend_mode_items[] = {
        {SEQ_BLEND_REPLACE, "REPLACE", 0, "Replace", ""},
-       {SEQ_CROSS, "CROSS", 0, "Cross", ""},
-       {SEQ_ADD, "ADD", 0, "Add", ""},
-       {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""},
-       {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""},
-       {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""},
-       {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""},
-       {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""},
-       {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""},
+       {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""},
+       {SEQ_TYPE_ADD, "ADD", 0, "Add", ""},
+       {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", ""},
+       {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""},
+       {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""},
+       {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""},
+       {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", ""},
+       {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Over Drop", ""},
        {0, NULL, 0, NULL, NULL}
 };
 
+static void rna_def_sequence_modifiers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+       StructRNA *srna;
+
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       RNA_def_property_srna(cprop, "SequenceModifiers");
+       srna = RNA_def_struct(brna, "SequenceModifiers", NULL);
+       RNA_def_struct_sdna(srna, "Sequence");
+       RNA_def_struct_ui_text(srna, "Strip Modifiers", "Collection of strip modifiers");
+
+       /* add modifier */
+       func = RNA_def_function(srna, "new", "rna_Sequence_modifier_new");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+       RNA_def_function_ui_description(func, "Add a new modifier");
+       parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the modifier");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       /* modifier to add */
+       parm = RNA_def_enum(func, "type", sequence_modifier_type_items, seqModifierType_ColorBalance, "", "Modifier type to add");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       /* return type */
+       parm = RNA_def_pointer(func, "modifier", "SequenceModifier", "", "Newly created modifier");
+       RNA_def_function_return(func, parm);
+
+       /* remove modifier */
+       func = RNA_def_function(srna, "remove", "rna_Sequence_modifier_remove");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+       RNA_def_function_ui_description(func, "Remove an existing modifier from the sequence");
+       /* modifier to remove */
+       parm = RNA_def_pointer(func, "modifier", "SequenceModifier", "", "Modifier to remove");
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+       /* clear all modifiers */
+       func = RNA_def_function(srna, "clear", "rna_Sequence_modifier_clear");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+       RNA_def_function_ui_description(func, "Remove all modifiers from the sequence");
+}
+
 static void rna_def_sequence(BlenderRNA *brna)
 {
        StructRNA *srna;
        PropertyRNA *prop;
 
        static const EnumPropertyItem seq_type_items[] = {
-               {SEQ_IMAGE, "IMAGE", 0, "Image", ""},
-               {SEQ_META, "META", 0, "Meta", ""},
-               {SEQ_SCENE, "SCENE", 0, "Scene", ""},
-               {SEQ_MOVIE, "MOVIE", 0, "Movie", ""},
-               {SEQ_MOVIECLIP, "MOVIECLIP", 0, "Clip", ""},
-               {SEQ_SOUND, "SOUND", 0, "Sound", ""},
-               {SEQ_CROSS, "CROSS", 0, "Cross", ""},
-               {SEQ_ADD, "ADD", 0, "Add", ""},
-               {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""},
-               {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""},
-               {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""},
-               {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""},
-               {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""},
-               {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""},
-               {SEQ_WIPE, "WIPE", 0, "Wipe", ""},
-               {SEQ_GLOW, "GLOW", 0, "Glow", ""},
-               {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", ""},
-               {SEQ_COLOR, "COLOR", 0, "Color", ""},
-               {SEQ_SPEED, "SPEED", 0, "Speed", ""},
-               {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""},
-               {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
+               {SEQ_TYPE_IMAGE, "IMAGE", 0, "Image", ""},
+               {SEQ_TYPE_META, "META", 0, "Meta", ""},
+               {SEQ_TYPE_SCENE, "SCENE", 0, "Scene", ""},
+               {SEQ_TYPE_MOVIE, "MOVIE", 0, "Movie", ""},
+               {SEQ_TYPE_MOVIECLIP, "MOVIECLIP", 0, "Clip", ""},
+               {SEQ_TYPE_MASK, "MASK", 0, "Mask", ""},
+               {SEQ_TYPE_SOUND_RAM, "SOUND", 0, "Sound", ""},
+               {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""},
+               {SEQ_TYPE_ADD, "ADD", 0, "Add", ""},
+               {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", ""},
+               {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""},
+               {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""},
+               {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""},
+               {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", ""},
+               {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Over Drop", ""},
+               {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", ""},
+               {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", ""},
+               {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", ""},
+               {SEQ_TYPE_COLOR, "COLOR", 0, "Color", ""},
+               {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", ""},
+               {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""},
+               {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
                {0, NULL, 0, NULL, NULL}
        };
        
@@ -1148,6 +1491,7 @@ static void rna_def_sequence(BlenderRNA *brna)
        
        prop = RNA_def_property(srna, "effect_fader", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
        RNA_def_property_float_sdna(prop, NULL, "effect_fader");
        RNA_def_property_ui_text(prop, "Effect fader position", "");
        RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1167,6 +1511,12 @@ static void rna_def_sequence(BlenderRNA *brna)
                                 "to this frame");
        RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
 
+       /* modifiers */
+       prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_struct_type(prop, "SequenceModifier");
+       RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting this strip");
+       rna_def_sequence_modifiers(brna, prop);
+
        RNA_api_sequence_strip(srna);
 }
 
@@ -1261,6 +1611,7 @@ static void rna_def_filter_video(StructRNA *srna)
        prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED);
        RNA_def_property_float_sdna(prop, NULL, "mul");
        RNA_def_property_range(prop, 0.0f, 20.0f);
+       RNA_def_property_float_default(prop, 1.0f);
        RNA_def_property_ui_text(prop, "Multiply Colors", "");
        RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
 
@@ -1268,6 +1619,7 @@ static void rna_def_filter_video(StructRNA *srna)
        RNA_def_property_float_sdna(prop, NULL, "sat");
        RNA_def_property_range(prop, 0.0f, 20.0f);
        RNA_def_property_ui_range(prop, 0.0f, 2.0f, 3, 3);
+       RNA_def_property_float_default(prop, 1.0f);
        RNA_def_property_ui_text(prop, "Saturation", "");
        RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
 
@@ -1351,7 +1703,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;
 
@@ -1359,6 +1711,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");
@@ -1381,6 +1737,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_strip",  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)
@@ -1505,6 +1870,8 @@ static void rna_def_movieclip(BlenderRNA *brna)
        RNA_def_struct_ui_text(srna, "MovieClip Sequence", "Sequence strip to load a video from the clip editor");
        RNA_def_struct_sdna(srna, "Sequence");
 
+       /* TODO - add clip property? */
+
        prop = RNA_def_property(srna, "undistort", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "clip_flag", SEQ_MOVIECLIP_RENDER_UNDISTORTED);
        RNA_def_property_ui_text(prop, "Undistort Clip", "Use the undistorted version of the clip");
@@ -1519,6 +1886,23 @@ static void rna_def_movieclip(BlenderRNA *brna)
        rna_def_input(srna);
 }
 
+static void rna_def_mask(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "MaskSequence", "Sequence");
+       RNA_def_struct_ui_text(srna, "Mask Sequence", "Sequence strip to load a video from a mask");
+       RNA_def_struct_sdna(srna, "Sequence");
+
+       prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Mask", "Mask that this sequence uses");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+
+       rna_def_filter_video(srna);
+       rna_def_input(srna);
+}
 
 static void rna_def_sound(BlenderRNA *brna)
 {
@@ -1802,52 +2186,28 @@ static void rna_def_speed_control(StructRNA *srna)
 }
 
 static EffectInfo def_effects[] = {
-       {"AddSequence", "Add Sequence",
-        "Add Sequence",
-        NULL, 2},
+       {"AddSequence", "Add Sequence", "Add Sequence", NULL, 2, FALSE},
        {"AdjustmentSequence", "Adjustment Layer Sequence",
-        "Sequence strip to perform filter adjustments to layers below",
-        rna_def_input, 0},
-       {"AlphaOverSequence", "Alpha Over Sequence",
-        "Alpha Over Sequence",
-        NULL, 2},
-       {"AlphaUnderSequence", "Alpha Under Sequence",
-        "Alpha Under Sequence",
-        NULL, 2},
+        "Sequence strip to perform filter adjustments to layers below", rna_def_input, 0, TRUE},
+       {"AlphaOverSequence", "Alpha Over Sequence", "Alpha Over Sequence", NULL, 2, FALSE},
+       {"AlphaUnderSequence", "Alpha Under Sequence", "Alpha Under Sequence", NULL, 2, FALSE},
        {"ColorSequence", "Color Sequence",
-        "Sequence strip creating an image filled with a single color",
-        rna_def_solid_color, 0},
-       {"CrossSequence", "Cross Sequence",
-        "Cross Sequence",
-        NULL, 2},
-       {"GammaCrossSequence", "Gamma Cross Sequence",
-        "Gamma Cross Sequence",
-        NULL, 2},
-       {"GlowSequence", "Glow Sequence",
-        "Sequence strip creating a glow effect",
-        rna_def_glow, 1},
-       {"MulticamSequence", "Multicam Select Sequence",
-        "Sequence strip to perform multicam editing",
-        rna_def_multicam, 0},
-       {"MultiplySequence", "Multiply Sequence",
-        "Multiply Sequence",
-        NULL, 2},
-       {"OverDropSequence", "Over Drop Sequence",
-        "Over Drop Sequence",
-        NULL, 2},
+        "Sequence strip creating an image filled with a single color", rna_def_solid_color, 0, FALSE},
+       {"CrossSequence", "Cross Sequence", "Cross Sequence", NULL, 2, FALSE},
+       {"GammaCrossSequence", "Gamma Cross Sequence", "Gamma Cross Sequence", NULL, 2, FALSE},
+       {"GlowSequence", "Glow Sequence", "Sequence strip creating a glow effect", rna_def_glow, 1, FALSE},
+       {"MulticamSequence", "Multicam Select Sequence", "Sequence strip to perform multicam editing",
+        rna_def_multicam, 0, FALSE},
+       {"MultiplySequence", "Multiply Sequence", "Multiply Sequence", NULL, 2, FALSE},
+       {"OverDropSequence", "Over Drop Sequence", "Over Drop Sequence", NULL, 2, FALSE},
        {"SpeedControlSequence", "SpeedControl Sequence",
-        "Sequence strip to control the speed of other strips",
-        rna_def_speed_control, 1},
-       {"SubtractSequence", "Subtract Sequence",
-        "Subtract Sequence",
-        NULL, 2},
+        "Sequence strip to control the speed of other strips", rna_def_speed_control, 1, FALSE},
+       {"SubtractSequence", "Subtract Sequence", "Subtract Sequence", NULL, 2, FALSE},
        {"TransformSequence", "Transform Sequence",
-        "Sequence strip applying affine transformations to other strips",
-        rna_def_transform, 1},
-       {"WipeSequence", "Wipe Sequence",
-        "Sequence strip creating a wipe transition",
-        rna_def_wipe, 1},
-       {"", "", "", NULL, 0}
+        "Sequence strip applying affine transformations to other strips", rna_def_transform, 1, FALSE},
+       {"WipeSequence", "Wipe Sequence", "Sequence strip creating a wipe transition",
+        rna_def_wipe, 1, FALSE},
+       {"", "", "", NULL, 0, FALSE}
 };
 
 static void rna_def_effects(BlenderRNA *brna)
@@ -1860,15 +2220,138 @@ 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);
        }
 }
 
+static void rna_def_modifier(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       static const EnumPropertyItem mask_input_type_items[] = {
+               {SEQUENCE_MASK_INPUT_STRIP, "STRIP", 0, "Strip", "Use sequencer strip as mask input"},
+               {SEQUENCE_MASK_INPUT_ID, "ID", 0, "Mask", "Use mask ID as mask input"},
+               {0, NULL, 0, NULL, NULL}
+       };
+
+       srna = RNA_def_struct(brna, "SequenceModifier", NULL);
+       RNA_def_struct_sdna(srna, "SequenceModifierData");
+       RNA_def_struct_ui_text(srna, "SequenceModifier", "Modifier for sequence strip");
+       RNA_def_struct_refine_func(srna, "rna_SequenceModifier_refine");
+       RNA_def_struct_path_func(srna, "rna_SequenceModifier_path");
+
+       prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SequenceModifier_name_set");
+       RNA_def_property_ui_text(prop, "Name", "");
+       RNA_def_struct_name_property(srna, prop);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+
+       prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_enum_items(prop, sequence_modifier_type_items);
+       RNA_def_property_ui_text(prop, "Type", "");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+
+       prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQUENCE_MODIFIER_MUTE);
+       RNA_def_property_ui_text(prop, "Mute", "Mute this modifier");
+       RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+
+       prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQUENCE_MODIFIER_EXPANDED);
+       RNA_def_property_ui_text(prop, "Expanded", "Mute expanded settings for the modifier");
+       RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
+
+       prop = RNA_def_property(srna, "input_mask_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "mask_input_type");
+       RNA_def_property_enum_items(prop, mask_input_type_items);
+       RNA_def_property_ui_text(prop, "Mask Input Type", "Type of input data used for mask");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+
+       prop = RNA_def_property(srna, "input_mask_strip",  PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "mask_sequence");
+       RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_SequenceModifier_otherSequence_poll");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Mask Strip", "Strip used as mask input for the modifier");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+
+       prop = RNA_def_property(srna, "input_mask_id", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "mask_id");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Mask", "Mask ID used as mask input for the modifier");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+}
+
+static void rna_def_colorbalance_modifier(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "ColorBalanceModifier", "SequenceModifier");
+       RNA_def_struct_sdna(srna, "ColorBalanceModifierData");
+       RNA_def_struct_ui_text(srna, "ColorBalanceModifier", "Color balance modifier for sequence strip");
+
+       prop = RNA_def_property(srna, "color_balance", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "SequenceColorBalanceData");
+
+       prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED);
+       RNA_def_property_float_sdna(prop, NULL, "color_multiply");
+       RNA_def_property_range(prop, 0.0f, 20.0f);
+       RNA_def_property_float_default(prop, 1.0f);
+       RNA_def_property_ui_text(prop, "Multiply Colors", "");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+}
+
+static void rna_def_curves_modifier(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "CurvesModifier", "SequenceModifier");
+       RNA_def_struct_sdna(srna, "CurvesModifierData");
+       RNA_def_struct_ui_text(srna, "CurvesModifier", "RGB curves modifier for sequence strip");
+
+       prop = RNA_def_property(srna, "curve_mapping", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "curve_mapping");
+       RNA_def_property_struct_type(prop, "CurveMapping");
+       RNA_def_property_ui_text(prop, "Curve Mapping", "");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+}
+
+static void rna_def_hue_modifier(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "HueCorrectModifier", "SequenceModifier");
+       RNA_def_struct_sdna(srna, "HueCorrectModifierData");
+       RNA_def_struct_ui_text(srna, "HueCorrectModifier", "Hue correction modifier for sequence strip");
+
+       prop = RNA_def_property(srna, "curve_mapping", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "curve_mapping");
+       RNA_def_property_struct_type(prop, "CurveMapping");
+       RNA_def_property_ui_text(prop, "Curve Mapping", "");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
+}
+
+static void rna_def_modifiers(BlenderRNA *brna)
+{
+       rna_def_modifier(brna);
+       rna_def_colorbalance_modifier(brna);
+       rna_def_curves_modifier(brna);
+       rna_def_hue_modifier(brna);
+}
+
 void RNA_def_sequencer(BlenderRNA *brna)
 {
+       rna_def_color_balance(brna);
+
        rna_def_strip_element(brna);
        rna_def_strip_proxy(brna);
        rna_def_strip_color_balance(brna);
@@ -1883,9 +2366,11 @@ void RNA_def_sequencer(BlenderRNA *brna)
        rna_def_scene(brna);
        rna_def_movie(brna);
        rna_def_movieclip(brna);
+       rna_def_mask(brna);
        rna_def_sound(brna);
        rna_def_effect(brna);
        rna_def_effects(brna);
+       rna_def_modifiers(brna);
 }
 
 #endif