Fix T78579: Proxy produces wrong preview when using Offset or Crop
Make sure that proxy and original images are scaled to same size before applying offset or crop. During testing, I discovered, that raw cache will lose information whether this image was proxy or not. Because of this, proxy images will not create this cache type. It would be fairly easy to implement this functionality for cache, but I have decided to not do it now, because I did not want to pass yet another mostly hard-coded bool flag to cache system. Since image is proxy, it should be fast to read anyway. In case of using offset property, code was modified to make sure we scale image only once. I also tried to make code more readable and streamlined and cleaned up surrounding functions a bit. Reviewed By: brecht Differential Revision: https://developer.blender.org/D8203
This commit is contained in:
parent
77f823a240
commit
5372924983
Notes:
blender-bot
2023-02-14 01:57:12 +01:00
Referenced by issue #78579, VSE: Proxy smaller than 100% produces wrong sizes in the preview window when using Offset or Crop for movie/image strips
|
@ -114,8 +114,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
|
|||
float cfra,
|
||||
clock_t begin,
|
||||
bool use_preprocess,
|
||||
const bool is_proxy_image,
|
||||
const bool is_preprocessed);
|
||||
const bool is_proxy_image);
|
||||
static ImBuf *seq_render_strip(const SeqRenderData *context,
|
||||
SeqRenderState *state,
|
||||
Sequence *seq,
|
||||
|
@ -2657,8 +2656,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
|
|||
Sequence *seq,
|
||||
float cfra,
|
||||
ImBuf *ibuf,
|
||||
const bool is_proxy_image,
|
||||
const bool is_preprocessed)
|
||||
const bool is_proxy_image)
|
||||
{
|
||||
Scene *scene = context->scene;
|
||||
float mul;
|
||||
|
@ -2672,15 +2670,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
|
|||
if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
|
||||
StripCrop c = {0};
|
||||
StripTransform t = {0};
|
||||
int sx, sy, dx, dy;
|
||||
|
||||
if (is_proxy_image) {
|
||||
double f = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
|
||||
|
||||
if (f != 1.0) {
|
||||
IMB_scalefastImBuf(ibuf, ibuf->x * f, ibuf->y * f);
|
||||
}
|
||||
}
|
||||
|
||||
if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
|
||||
c = *seq->strip->crop;
|
||||
|
@ -2689,33 +2678,41 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
|
|||
t = *seq->strip->transform;
|
||||
}
|
||||
|
||||
if (is_preprocessed) {
|
||||
double xscale = scene->r.xsch ? ((double)context->rectx / (double)scene->r.xsch) : 1.0;
|
||||
double yscale = scene->r.ysch ? ((double)context->recty / (double)scene->r.ysch) : 1.0;
|
||||
if (seq->flag & SEQ_USE_TRANSFORM) {
|
||||
t.xofs *= xscale;
|
||||
t.yofs *= yscale;
|
||||
}
|
||||
if (seq->flag & SEQ_USE_CROP) {
|
||||
c.left *= xscale;
|
||||
c.right *= xscale;
|
||||
c.top *= yscale;
|
||||
c.bottom *= yscale;
|
||||
/* Calculate scale factor for current image if needed. */
|
||||
double scale_factor, image_scale_factor = 1.0;
|
||||
if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
|
||||
scale_factor = image_scale_factor = (double)scene->r.size / 100;
|
||||
}
|
||||
else {
|
||||
scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
|
||||
if (!is_proxy_image) {
|
||||
image_scale_factor = scale_factor;
|
||||
}
|
||||
}
|
||||
|
||||
if (image_scale_factor != 1.0) {
|
||||
if (context->for_render) {
|
||||
IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
|
||||
}
|
||||
else {
|
||||
IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
|
||||
}
|
||||
}
|
||||
|
||||
t.xofs *= scale_factor;
|
||||
t.yofs *= scale_factor;
|
||||
c.left *= scale_factor;
|
||||
c.right *= scale_factor;
|
||||
c.top *= scale_factor;
|
||||
c.bottom *= scale_factor;
|
||||
|
||||
int sx, sy, dx, dy;
|
||||
sx = ibuf->x - c.left - c.right;
|
||||
sy = ibuf->y - c.top - c.bottom;
|
||||
|
||||
if (seq->flag & SEQ_USE_TRANSFORM) {
|
||||
if (is_preprocessed) {
|
||||
dx = context->rectx;
|
||||
dy = context->recty;
|
||||
}
|
||||
else {
|
||||
dx = scene->r.xsch;
|
||||
dy = scene->r.ysch;
|
||||
}
|
||||
dx = context->rectx;
|
||||
dy = context->recty;
|
||||
}
|
||||
else {
|
||||
dx = sx;
|
||||
|
@ -2724,19 +2721,15 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
|
|||
|
||||
if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
|
||||
t.yofs >= dy) {
|
||||
make_black_ibuf(ibuf);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
|
||||
|
||||
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
|
||||
sequencer_imbuf_assign_spaces(scene, i);
|
||||
|
||||
IMB_metadata_copy(i, ibuf);
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
||||
ibuf = i;
|
||||
}
|
||||
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
|
||||
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
|
||||
sequencer_imbuf_assign_spaces(scene, i);
|
||||
IMB_metadata_copy(i, ibuf);
|
||||
IMB_freeImBuf(ibuf);
|
||||
ibuf = i;
|
||||
}
|
||||
|
||||
if (seq->flag & SEQ_FLIPX) {
|
||||
|
@ -3097,7 +3090,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
|
|||
|
||||
if (view_id != context->view_id) {
|
||||
ibufs_arr[view_id] = seq_render_preprocess_ibuf(
|
||||
&localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false, false);
|
||||
&localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3214,7 +3207,7 @@ static ImBuf *seq_render_movie_strip(
|
|||
|
||||
if (view_id != context->view_id) {
|
||||
ibuf_arr[view_id] = seq_render_preprocess_ibuf(
|
||||
&localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false, false);
|
||||
&localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3804,8 +3797,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
|
|||
float cfra,
|
||||
clock_t begin,
|
||||
bool use_preprocess,
|
||||
const bool is_proxy_image,
|
||||
const bool is_preprocessed)
|
||||
const bool is_proxy_image)
|
||||
{
|
||||
if (context->is_proxy_render == false &&
|
||||
(ibuf->x != context->rectx || ibuf->y != context->recty)) {
|
||||
|
@ -3814,11 +3806,17 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
|
|||
|
||||
if (use_preprocess) {
|
||||
float cost = seq_estimate_render_cost_end(context->scene, begin);
|
||||
BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
|
||||
|
||||
/* TODO (Richard): It should be possible to store in cache if image is proxy,
|
||||
* but it adds quite a bit of complexity. Since proxies are fast to read, I would
|
||||
* rather simplify existing code a bit. */
|
||||
if (!is_proxy_image) {
|
||||
BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
|
||||
}
|
||||
|
||||
/* Reset timer so we can get partial render time. */
|
||||
begin = seq_estimate_render_cost_begin();
|
||||
ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
|
||||
ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image);
|
||||
}
|
||||
|
||||
float cost = seq_estimate_render_cost_end(context->scene, begin);
|
||||
|
@ -3834,11 +3832,6 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
|
|||
ImBuf *ibuf = NULL;
|
||||
bool use_preprocess = false;
|
||||
bool is_proxy_image = false;
|
||||
/* all effects are handled similarly with the exception of speed effect */
|
||||
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT :
|
||||
seq->type;
|
||||
bool is_preprocessed = !ELEM(
|
||||
type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
|
||||
|
||||
clock_t begin = seq_estimate_render_cost_begin();
|
||||
|
||||
|
@ -3855,7 +3848,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
|
|||
if (ibuf) {
|
||||
use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
|
||||
ibuf = seq_render_preprocess_ibuf(
|
||||
context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image, is_preprocessed);
|
||||
context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image);
|
||||
}
|
||||
|
||||
if (ibuf == NULL) {
|
||||
|
|
Loading…
Reference in New Issue