diff options
author | Sergey Sharybin <sergey@blender.org> | 2022-11-10 19:56:32 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2022-11-10 20:01:04 +0300 |
commit | d3121fe4ecdf76c7d35d269624aecb8af3d9fa73 (patch) | |
tree | 7aace3c12d967f0d92f09bb270858b3748f39aab | |
parent | 02c23e1613b2ab8b411dcb247d7a10cccb6a4f77 (diff) |
Fix T100654: Distortion node freezes on empty input
Perform an early output when the input is empty, avoiding division by
zero and attempt to run LM solver on an inf values.
-rw-r--r-- | source/blender/compositor/operations/COM_MovieDistortionOperation.cc | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc index b89a48f2a39..353f3da14d7 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc @@ -78,34 +78,41 @@ void MovieDistortionOperation::execute_pixel_sampled(float output[4], float y, PixelSampler /*sampler*/) { - if (distortion_ != nullptr) { - /* float overscan = 0.0f; */ - const float pixel_aspect = pixel_aspect_; - const float w = float(this->get_width()) /* / (1 + overscan) */; - const float h = float(this->get_height()) /* / (1 + overscan) */; - const float aspx = w / float(calibration_width_); - const float aspy = h / float(calibration_height_); - float in[2]; - float out[2]; - - in[0] = (x /* - 0.5 * overscan * w */) / aspx; - in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect; + const int width = this->get_width(); + const int height = this->get_height(); + if (distortion_ == nullptr || width == 0 || height == 0) { + /* When there is no precomputed distortion pass-through the coordinate as-is to the input + * samples. + * If the frame size is zero do the same and bypass any math. In theory it is probably more + * correct to zero the output but it is easier and safe to let the input to do so than to deal + * with possible different number of channels here. */ + input_operation_->read_sampled(output, x, y, PixelSampler::Bilinear); + return; + } - if (apply_) { - BKE_tracking_distortion_undistort_v2(distortion_, in, out); - } - else { - BKE_tracking_distortion_distort_v2(distortion_, in, out); - } + /* float overscan = 0.0f; */ + const float w = float(width) /* / (1 + overscan) */; + const float h = float(height) /* / (1 + overscan) */; + const float pixel_aspect = pixel_aspect_; + const float aspx = w / float(calibration_width_); + const float aspy = h / float(calibration_height_); + float in[2]; + float out[2]; - float u = out[0] * aspx /* + 0.5 * overscan * w */, - v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect; + in[0] = (x /* - 0.5 * overscan * w */) / aspx; + in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect; - input_operation_->read_sampled(output, u, v, PixelSampler::Bilinear); + if (apply_) { + BKE_tracking_distortion_undistort_v2(distortion_, in, out); } else { - input_operation_->read_sampled(output, x, y, PixelSampler::Bilinear); + BKE_tracking_distortion_distort_v2(distortion_, in, out); } + + float u = out[0] * aspx /* + 0.5 * overscan * w */, + v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect; + + input_operation_->read_sampled(output, u, v, PixelSampler::Bilinear); } bool MovieDistortionOperation::determine_depending_area_of_interest( |