Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-08-11 18:37:58 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-08-11 18:37:58 +0400
commita794e19346ab6ee30e14e8175c153b03fa6cb7a5 (patch)
tree611279ea79071664c525cc978758b92758b652a5 /source/blender/blenkernel
parentbe4ae581fff820cefc21d150080e13f621b99cdd (diff)
Sequencer: support for masked color balance
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h10
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c13
-rw-r--r--source/blender/blenkernel/intern/sequencer.c180
3 files changed, 139 insertions, 64 deletions
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 78e65fe3ea6..fee1db99c5c 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 911b6b00b98..2380596c6ad 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -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;
+}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 4f1b324bc28..920588d9f47 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -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
}