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:
-rw-r--r--source/blender/sequencer/intern/render.c156
1 files changed, 75 insertions, 81 deletions
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index 96c881c9c5f..f892f1c1b41 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -459,50 +459,81 @@ static bool seq_input_have_to_preprocess(const SeqRenderData *context,
typedef struct ImageTransformThreadInitData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
- StripTransform *transform;
- float scale_to_fit;
- float image_scale_factor;
+ Sequence *seq;
float preview_scale_factor;
+ bool is_proxy_image;
bool for_render;
} ImageTransformThreadInitData;
typedef struct ImageTransformThreadData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
- StripTransform *transform;
- float scale_to_fit;
+ Sequence *seq;
/* image_scale_factor is used to scale proxies to correct preview size. */
float image_scale_factor;
/* Preview scale factor is needed to correct translation to match preview size. */
float preview_scale_factor;
+ float crop_scale_factor;
bool for_render;
int start_line;
int tot_line;
} ImageTransformThreadData;
-static void sequencer_image_transform_init(void *handle_v,
- int start_line,
- int tot_line,
- void *init_data_v)
+/**
+ * Effect, mask and scene in strip input strips are rendered in preview resolution.
+ * They are already down-scaled. #input_preprocess() does not expect this to happen.
+ * Other strip types are rendered with original media resolution, unless proxies are
+ * enabled for them. With proxies `is_proxy_image` will be set correctly to true.
+ */
+static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_image)
+{
+ if (is_proxy_image) {
+ return true;
+ }
+ if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->type == SEQ_TYPE_MASK ||
+ seq->type == SEQ_TYPE_META ||
+ (seq->type == SEQ_TYPE_SCENE && ((seq->flag & SEQ_SCENE_STRIPS) != 0))) {
+ return true;
+ }
+ return false;
+}
+
+static void sequencer_image_crop_transform_init(void *handle_v,
+ int start_line,
+ int tot_line,
+ void *init_data_v)
{
ImageTransformThreadData *handle = (ImageTransformThreadData *)handle_v;
const ImageTransformThreadInitData *init_data = (ImageTransformThreadInitData *)init_data_v;
handle->ibuf_source = init_data->ibuf_source;
handle->ibuf_out = init_data->ibuf_out;
- handle->transform = init_data->transform;
- handle->image_scale_factor = init_data->image_scale_factor;
+ handle->seq = init_data->seq;
+
handle->preview_scale_factor = init_data->preview_scale_factor;
- handle->for_render = init_data->for_render;
+ if (seq_need_scale_to_render_size(init_data->seq, init_data->is_proxy_image)) {
+ handle->image_scale_factor = 1.0f;
+ }
+ else {
+ handle->image_scale_factor = handle->preview_scale_factor;
+ }
+
+ /* Proxy image is smaller, so crop values must be corrected by proxy scale factor.
+ * Proxy scale factor always matches preview_scale_factor. */
+ handle->crop_scale_factor = seq_need_scale_to_render_size(init_data->seq,
+ init_data->is_proxy_image) ?
+ init_data->preview_scale_factor :
+ 1.0f;
+ handle->for_render = init_data->for_render;
handle->start_line = start_line;
handle->tot_line = tot_line;
}
-static void *sequencer_image_transform_do_thread(void *data_v)
+static void *sequencer_image_crop_transform_do_thread(void *data_v)
{
const ImageTransformThreadData *data = (ImageTransformThreadData *)data_v;
- const StripTransform *transform = data->transform;
+ const StripTransform *transform = data->seq->strip->transform;
const float scale_x = transform->scale_x * data->image_scale_factor;
const float scale_y = transform->scale_y * data->image_scale_factor;
const float image_center_offs_x = (data->ibuf_out->x - data->ibuf_source->x) / 2;
@@ -515,8 +546,19 @@ static void *sequencer_image_transform_do_thread(void *data_v)
(const float[]){translate_x, translate_y},
transform->rotation,
(const float[]){scale_x, scale_y});
- invert_m3(transform_matrix);
transform_pivot_set_m3(transform_matrix, pivot);
+ invert_m3(transform_matrix);
+
+ /* Image crop is done by offsetting image boundary limits. */
+ const StripCrop *c = data->seq->strip->crop;
+ const int left = c->left * data->crop_scale_factor;
+ const int right = c->right * data->crop_scale_factor;
+ const int top = c->top * data->crop_scale_factor;
+ const int bottom = c->bottom * data->crop_scale_factor;
+
+ const float source_pixel_range_max[2] = {data->ibuf_source->x - right,
+ data->ibuf_source->y - top};
+ const float source_pixel_range_min[2] = {left, bottom};
const int width = data->ibuf_out->x;
for (int yi = data->start_line; yi < data->start_line + data->tot_line; yi++) {
@@ -524,6 +566,11 @@ static void *sequencer_image_transform_do_thread(void *data_v)
float uv[2] = {xi, yi};
mul_v2_m3v2(uv, transform_matrix, uv);
+ if (source_pixel_range_min[0] >= uv[0] || uv[0] >= source_pixel_range_max[0] ||
+ source_pixel_range_min[1] >= uv[1] || uv[1] >= source_pixel_range_max[1]) {
+ continue;
+ }
+
if (data->for_render) {
bilinear_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi);
}
@@ -571,25 +618,6 @@ static void multibuf(ImBuf *ibuf, const float fmul)
}
}
-/**
- * Effect, mask and scene in strip input strips are rendered in preview resolution.
- * They are already down-scaled. #input_preprocess() does not expect this to happen.
- * Other strip types are rendered with original media resolution, unless proxies are
- * enabled for them. With proxies `is_proxy_image` will be set correctly to true.
- */
-static bool seq_need_scale_to_render_size(const Sequence *seq, bool is_proxy_image)
-{
- if (is_proxy_image) {
- return true;
- }
- if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->type == SEQ_TYPE_MASK ||
- seq->type == SEQ_TYPE_META ||
- (seq->type == SEQ_TYPE_SCENE && ((seq->flag & SEQ_SCENE_STRIPS) != 0))) {
- return true;
- }
- return false;
-}
-
static ImBuf *input_preprocess(const SeqRenderData *context,
Sequence *seq,
float timeline_frame,
@@ -608,46 +636,8 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
IMB_filtery(preprocessed_ibuf);
}
- /* Get scale factor if preview resolution doesn't match project resolution. */
- float preview_scale_factor;
- if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
- preview_scale_factor = (float)scene->r.size / 100;
- }
- else {
- preview_scale_factor = SEQ_rendersize_to_scale_factor(context->preview_render_size);
- }
-
- if (sequencer_use_crop(seq)) {
- /* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */
- preprocessed_ibuf = IMB_makeSingleUser(ibuf);
- ibuf = preprocessed_ibuf;
-
- const int width = ibuf->x;
- const int height = ibuf->y;
- const StripCrop *c = seq->strip->crop;
-
- /* Proxy image is smaller, so crop values must be corrected by proxy scale factor.
- * Proxy scale factor always matches preview_scale_factor. */
- const float crop_scale_factor = seq_need_scale_to_render_size(seq, is_proxy_image) ?
- preview_scale_factor :
- 1.0f;
- const int left = c->left * crop_scale_factor;
- const int right = c->right * crop_scale_factor;
- const int top = c->top * crop_scale_factor;
- const int bottom = c->bottom * crop_scale_factor;
- const float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- /* Left. */
- IMB_rectfill_area_replace(preprocessed_ibuf, col, 0, 0, left, height);
- /* Bottom. */
- IMB_rectfill_area_replace(preprocessed_ibuf, col, left, 0, width, bottom);
- /* Right. */
- IMB_rectfill_area_replace(preprocessed_ibuf, col, width - right, bottom, width, height);
- /* Top. */
- IMB_rectfill_area_replace(preprocessed_ibuf, col, left, height - top, width - right, height);
- }
-
- if (sequencer_use_transform(seq) || context->rectx != ibuf->x || context->recty != ibuf->y) {
+ if (sequencer_use_crop(seq) || sequencer_use_transform(seq) || context->rectx != ibuf->x ||
+ context->recty != ibuf->y) {
const int x = context->rectx;
const int y = context->recty;
preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
@@ -655,20 +645,24 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
ImageTransformThreadInitData init_data = {NULL};
init_data.ibuf_source = ibuf;
init_data.ibuf_out = preprocessed_ibuf;
- init_data.transform = seq->strip->transform;
- if (seq_need_scale_to_render_size(seq, is_proxy_image)) {
- init_data.image_scale_factor = 1.0f;
+ init_data.seq = seq;
+ init_data.is_proxy_image = is_proxy_image;
+
+ /* Get scale factor if preview resolution doesn't match project resolution. */
+ if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
+ init_data.preview_scale_factor = (float)scene->r.size / 100;
}
else {
- init_data.image_scale_factor = preview_scale_factor;
+ init_data.preview_scale_factor = SEQ_rendersize_to_scale_factor(
+ context->preview_render_size);
}
- init_data.preview_scale_factor = preview_scale_factor;
+
init_data.for_render = context->for_render;
IMB_processor_apply_threaded(context->recty,
sizeof(ImageTransformThreadData),
&init_data,
- sequencer_image_transform_init,
- sequencer_image_transform_do_thread);
+ sequencer_image_crop_transform_init,
+ sequencer_image_crop_transform_do_thread);
seq_imbuf_assign_spaces(scene, preprocessed_ibuf);
IMB_metadata_copy(preprocessed_ibuf, ibuf);
IMB_freeImBuf(ibuf);