From BlenderWiki

Jump to: navigation, search

Sequencer Modifiers

Main idea of modifiers is to be able apply color grading on sequences without cluttering sequencer with bunch of effects.


General Notes

Modifier stack is implemented as a per-Sequence list of modifiers. Each modifier is defined in the same way as object modifiers: sequence modifier has got modifier data structure which is being saved to file and modifier type info, which is only used run-time and defines how modifier should be applied.

Modifier data structure consists of two parts, one of them is a header which is common to all sequence modifiers:

typedef struct SequenceModifierData {
	struct SequenceModifierData *next, *prev;
	int type, flag;
	char name[64]; /* MAX_NAME */
	/* mask input, either sequence or maks ID */
	int mask_input_type, pad;
	struct Sequence *mask_sequence;
	struct Mask     *mask_id;
} SequenceModifierData;


  • Type defines which modifier it is
  • Name is a user-defined interface name of modifier
  • mask_input type defines which entity to use as a mask. It could be either Strip or Mask ID datablock.

This structure should be a first property of any other sequence modifier data, so it'll look like

typedef struct SequenceModifierData {
	/* common header */
	SequenceModifierData modifier;
	/* modifier-specific data */
} MySequenceModifierData;

Modifier type information structure looks like

typedef struct SequenceModifierTypeInfo {
	/* default name for the modifier */
	char name[64];  /* MAX_NAME */
	/* DNA structure name used on load/save filed */
	char struct_name[64];  /* MAX_NAME */
	/* size of modifier data structure, used by allocation */
	int struct_size;
	/* data initialization */
	void (*init_data) (struct SequenceModifierData *smd);
	/* free data used by modifier,
	 * only modifier-specific data should be freed, modifier descriptor would
	 * be freed outside of this callback
	void (*free_data) (struct SequenceModifierData *smd);
	/* copy data from one modifier to another */
	void (*copy_data) (struct SequenceModifierData *smd, struct SequenceModifierData *target);
	/* apply modifier on a given image buffer */
	struct ImBuf* (*apply) (struct SequenceModifierData *smd, struct ImBuf *ibuf, struct ImBuf *mask);
} SequenceModifierTypeInfo;

Every property is documented there and it should be pretty obvious what's going on there.

Modifier stack is applying on sequence's image buffer on top of all other post-processing.

Apply callback of sequence modifiers could be multithreaded. All current modifiers are working on pixel level and using IMB_processor_apply_threaded to apply color corrections.


Cache system was extended a bit to make it possible to grade heavy exr files real-time. To reach this goal it was added extra cache level where original image buffers are storing, so when properties of color corrections are changing it's not needed to reload file from disk on every property change. This cache stores original image buffers for current frame only which is enough to make grading comfortable to work without wasting lots of memory.

Functions to operate with this cache are:

  • BKE_sequencer_preprocessed_cache_get - get original image buffer from cache
  • BKE_sequencer_preprocessed_cache_put - put original buffer to cache. This function will insure that images only for current frame are stored in cache
  • BKE_sequencer_preprocessed_cache_cleanup_sequence - clean cache for given strip


WIP SequenceModifiers.png

Modifier stack is available in sequence properties panel. Using modifiers is pretty much straightforward.

First of all modifier should be added to stack. Add Strip Modifier button is used for this. Currently only Color Balance, HUE Correct, RGB Curves and Bright/Contrast modifiers are supported.

When new modifier is added it's properties would be displayed below.

Eye button could be used to mute the modifier.

Strip / Mask enumerator is sued to define what defines mask used for this modifier. It could be another strip or mask datablock. Depending on this setting Mask entry would be used to select either strip or mask datablock. Masks are used to control influence of modifier.

Below mask settings it'll be modifier specified settings: for HUE Correct and RGB Curves it'll be curves widget, for Color Balance it'll be color wheels.


  • Integrate tone maps and display transform from OCIO into sequencer rendering pipeline. Currently sequencer is working in sRGB 2.2 Gamma space, and only it's result is being affected by tonemap which is stupid.
  • look into interface improvement, like make special region and put settings in horizontal layout. Vertical layout isn't so much nice to work with in this case.