From fa62874b44f75516be168f8eebc6e78283a8abd2 Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Wed, 29 Jul 2026 18:38:13 -0700 Subject: [PATCH 1/8] changed in place blurring to buffer --- src/modules/opencv/filter_opencv_tracker.cpp | 39 +++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index ec0a89c56..544a39c24 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -468,18 +468,19 @@ static int filter_get_image(mlt_frame frame, } if (blur > 0 && data->boundingBox.width > 1 && data->boundingBox.height > 1) { + cv::Mat roi = cvFrame(data->boundingBox); + cv::Mat blurredRoi; + roi.copyTo(blurredRoi); + bool do_blur = true; + switch (mlt_properties_get_int(filter_properties, "blur_type")) { case 1: // Gaussian Blur - cv::GaussianBlur(cvFrame(data->boundingBox), - cvFrame(data->boundingBox), - cv::Size(0, 0), - blur); + cv::GaussianBlur(roi, blurredRoi, cv::Size(0, 0), blur); break; case 2: // Pixelate { - cv::Mat roi = cvFrame(data->boundingBox); cv::Mat res; cv::resize(roi, res, @@ -487,17 +488,17 @@ static int filter_get_image(mlt_frame frame, MAX(2, data->boundingBox.height / blur)), cv::INTER_NEAREST); cv::resize(res, - roi, + blurredRoi, cv::Size(data->boundingBox.width, data->boundingBox.height), 0, 0, cv::INTER_NEAREST); - cvFrame(data->boundingBox) = roi; } break; case 3: // Opaque fill, handled in shape_width option shape_width = -1; + do_blur = false; break; case 0: // Median Blur @@ -506,12 +507,32 @@ static int filter_get_image(mlt_frame frame, // median blur param must be odd and, minimum 3 ++blur; } - cv::medianBlur(cvFrame(data->boundingBox), cvFrame(data->boundingBox), blur); + cv::medianBlur(roi, blurredRoi, blur); break; default: - // Do nothing + do_blur = false; break; } + + if (do_blur) { + switch (mlt_properties_get_int(filter_properties, "shape")) { + case 1: + // Ellipse + { + cv::Mat mask = cv::Mat::zeros(roi.size(), CV_8UC1); + cv::RotatedRect bounding = cv::RotatedRect(cv::Point2f(data->boundingBox.width / 2.0f, + data->boundingBox.height / 2.0f), + cv::Size2f(data->boundingBox.width, data->boundingBox.height), + 0); + cv::ellipse(mask, bounding, cv::Scalar(255), -1, 1); + blurredRoi.copyTo(roi, mask); + } + break; + default: + blurredRoi.copyTo(roi); + break; + } + } } // Paint overlay shape From d452d4594e617c6ed0a694654905363336108aa7 Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Fri, 31 Jul 2026 12:55:54 -0700 Subject: [PATCH 2/8] unnecessary copy and change constant to enum --- src/modules/opencv/filter_opencv_tracker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index 544a39c24..b7bc9c029 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -470,7 +470,6 @@ static int filter_get_image(mlt_frame frame, if (blur > 0 && data->boundingBox.width > 1 && data->boundingBox.height > 1) { cv::Mat roi = cvFrame(data->boundingBox); cv::Mat blurredRoi; - roi.copyTo(blurredRoi); bool do_blur = true; switch (mlt_properties_get_int(filter_properties, "blur_type")) { @@ -524,7 +523,7 @@ static int filter_get_image(mlt_frame frame, data->boundingBox.height / 2.0f), cv::Size2f(data->boundingBox.width, data->boundingBox.height), 0); - cv::ellipse(mask, bounding, cv::Scalar(255), -1, 1); + cv::ellipse(mask, bounding, cv::Scalar(255), -1, cv::LINE_4); blurredRoi.copyTo(roi, mask); } break; From 72bf9d8af52c0cc42b238bd60ee632d98e8634db Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Fri, 31 Jul 2026 12:57:53 -0700 Subject: [PATCH 3/8] change existing value to enum --- src/modules/opencv/filter_opencv_tracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index b7bc9c029..43b157d55 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -566,7 +566,7 @@ static int filter_get_image(mlt_frame frame, bounding, cv::Scalar(shape_color.r, shape_color.g, shape_color.b), shape_width, - 1); + cv::LINE_4); } break; case 0: From 10c125b181187541c9503418ba2b39701e579067 Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Mon, 3 Aug 2026 17:14:34 -0700 Subject: [PATCH 4/8] correctly draws clipped shape --- src/modules/opencv/filter_opencv_tracker.cpp | 51 +++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index 43b157d55..cd8dc0a4a 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -445,30 +445,33 @@ static int filter_get_image(mlt_frame frame, position, data->producer_in + data->producer_length); } - // ensure bounding box is within the frame boundaries or OpenCV will crash - if (data->boundingBox.x > *width) { - data->boundingBox.x = *width; - data->boundingBox.width = 0; - } else if (data->boundingBox.x < 0) { - data->boundingBox.width = MAX(0, data->boundingBox.width + data->boundingBox.x); - data->boundingBox.x = 0; - } - if (data->boundingBox.y > *height) { - data->boundingBox.y = *height; - data->boundingBox.height = 0; - } else if (data->boundingBox.y < 0) { - data->boundingBox.height = MAX(0, data->boundingBox.height + data->boundingBox.y); - data->boundingBox.y = 0; - } - if (data->boundingBox.x + data->boundingBox.width > *width) { - data->boundingBox.width = *width - data->boundingBox.x; - } - if (data->boundingBox.y + data->boundingBox.height > *height) { - data->boundingBox.height = *height - data->boundingBox.y; - } if (blur > 0 && data->boundingBox.width > 1 && data->boundingBox.height > 1) { - cv::Mat roi = cvFrame(data->boundingBox); + // ensure bounding box is within the frame boundaries or OpenCV will crash + // this only affects the blurring functions, drawn shapes are handled properly + cv::Rect clippedBox = data->boundingBox; + if (clippedBox.x > *width) { + clippedBox.x = *width; + clippedBox.width = 0; + } else if (clippedBox.x < 0) { + clippedBox.width = MAX(0, clippedBox.width + clippedBox.x); + clippedBox.x = 0; + } + if (clippedBox.y > *height) { + clippedBox.y = *height; + clippedBox.height = 0; + } else if (clippedBox.y < 0) { + clippedBox.height = MAX(0, clippedBox.height + clippedBox.y); + clippedBox.y = 0; + } + if (clippedBox.x + clippedBox.width > *width) { + clippedBox.width = *width - clippedBox.x; + } + if (clippedBox.y + clippedBox.height > *height) { + clippedBox.height = *height - clippedBox.y; + } + + cv::Mat roi = cvFrame(clippedBox); cv::Mat blurredRoi; bool do_blur = true; @@ -519,8 +522,8 @@ static int filter_get_image(mlt_frame frame, // Ellipse { cv::Mat mask = cv::Mat::zeros(roi.size(), CV_8UC1); - cv::RotatedRect bounding = cv::RotatedRect(cv::Point2f(data->boundingBox.width / 2.0f, - data->boundingBox.height / 2.0f), + cv::RotatedRect bounding = cv::RotatedRect(cv::Point2f(data->boundingBox.x < 0 ? data->boundingBox.width / 2.0f + data->boundingBox.x : data->boundingBox.width / 2.0f, + data->boundingBox.y < 0 ? data->boundingBox.height / 2.0f + data->boundingBox.y : data->boundingBox.height / 2.0f), cv::Size2f(data->boundingBox.width, data->boundingBox.height), 0); cv::ellipse(mask, bounding, cv::Scalar(255), -1, cv::LINE_4); From 153fda63e98dee94da3546dd727c52447a334ac7 Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Mon, 3 Aug 2026 17:38:44 -0700 Subject: [PATCH 5/8] fix crash by checking if blur region exists --- src/modules/opencv/filter_opencv_tracker.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index cd8dc0a4a..29147099f 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -446,7 +446,11 @@ static int filter_get_image(mlt_frame frame, data->producer_in + data->producer_length); } - if (blur > 0 && data->boundingBox.width > 1 && data->boundingBox.height > 1) { + if (blur > 0 && + data->boundingBox.width > 1 && + data->boundingBox.height > 1 && + data->boundingBox.x > - data->boundingBox.width && data->boundingBox.x < *width && + data->boundingBox.y > - data->boundingBox.height && data->boundingBox.y < *height) { // ensure bounding box is within the frame boundaries or OpenCV will crash // this only affects the blurring functions, drawn shapes are handled properly cv::Rect clippedBox = data->boundingBox; From d6b39560a5a9335522af4053cff62a65c9b6996d Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Mon, 3 Aug 2026 17:51:50 -0700 Subject: [PATCH 6/8] fix pixelate crash --- src/modules/opencv/filter_opencv_tracker.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index 29147099f..c20f2baff 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -449,8 +449,10 @@ static int filter_get_image(mlt_frame frame, if (blur > 0 && data->boundingBox.width > 1 && data->boundingBox.height > 1 && - data->boundingBox.x > - data->boundingBox.width && data->boundingBox.x < *width && - data->boundingBox.y > - data->boundingBox.height && data->boundingBox.y < *height) { + data->boundingBox.x > - data->boundingBox.width && + data->boundingBox.x < *width && + data->boundingBox.y > - data->boundingBox.height && + data->boundingBox.y < *height) { // ensure bounding box is within the frame boundaries or OpenCV will crash // this only affects the blurring functions, drawn shapes are handled properly cv::Rect clippedBox = data->boundingBox; @@ -490,12 +492,12 @@ static int filter_get_image(mlt_frame frame, cv::Mat res; cv::resize(roi, res, - cv::Size(MAX(2, data->boundingBox.width / blur), - MAX(2, data->boundingBox.height / blur)), + cv::Size(MAX(2, clippedBox.width / blur), + MAX(2, clippedBox.height / blur)), cv::INTER_NEAREST); cv::resize(res, blurredRoi, - cv::Size(data->boundingBox.width, data->boundingBox.height), + cv::Size(clippedBox.width, clippedBox.height), 0, 0, cv::INTER_NEAREST); From 2ecc3cbafda92a12e0090be608c155e748cab489 Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Mon, 3 Aug 2026 17:57:08 -0700 Subject: [PATCH 7/8] operations optimization --- src/modules/opencv/filter_opencv_tracker.cpp | 37 +++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index c20f2baff..365c3124d 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -446,37 +446,8 @@ static int filter_get_image(mlt_frame frame, data->producer_in + data->producer_length); } - if (blur > 0 && - data->boundingBox.width > 1 && - data->boundingBox.height > 1 && - data->boundingBox.x > - data->boundingBox.width && - data->boundingBox.x < *width && - data->boundingBox.y > - data->boundingBox.height && - data->boundingBox.y < *height) { - // ensure bounding box is within the frame boundaries or OpenCV will crash - // this only affects the blurring functions, drawn shapes are handled properly - cv::Rect clippedBox = data->boundingBox; - if (clippedBox.x > *width) { - clippedBox.x = *width; - clippedBox.width = 0; - } else if (clippedBox.x < 0) { - clippedBox.width = MAX(0, clippedBox.width + clippedBox.x); - clippedBox.x = 0; - } - if (clippedBox.y > *height) { - clippedBox.y = *height; - clippedBox.height = 0; - } else if (clippedBox.y < 0) { - clippedBox.height = MAX(0, clippedBox.height + clippedBox.y); - clippedBox.y = 0; - } - if (clippedBox.x + clippedBox.width > *width) { - clippedBox.width = *width - clippedBox.x; - } - if (clippedBox.y + clippedBox.height > *height) { - clippedBox.height = *height - clippedBox.y; - } - + cv::Rect clippedBox = data->boundingBox & cv::Rect(0, 0, *width, *height); + if (blur > 0 && clippedBox.width > 1 && clippedBox.height > 1) { cv::Mat roi = cvFrame(clippedBox); cv::Mat blurredRoi; bool do_blur = true; @@ -528,8 +499,8 @@ static int filter_get_image(mlt_frame frame, // Ellipse { cv::Mat mask = cv::Mat::zeros(roi.size(), CV_8UC1); - cv::RotatedRect bounding = cv::RotatedRect(cv::Point2f(data->boundingBox.x < 0 ? data->boundingBox.width / 2.0f + data->boundingBox.x : data->boundingBox.width / 2.0f, - data->boundingBox.y < 0 ? data->boundingBox.height / 2.0f + data->boundingBox.y : data->boundingBox.height / 2.0f), + cv::RotatedRect bounding = cv::RotatedRect(cv::Point2f(data->boundingBox.x + data->boundingBox.width / 2.0f - clippedBox.x, + data->boundingBox.y + data->boundingBox.height / 2.0f - clippedBox.y), cv::Size2f(data->boundingBox.width, data->boundingBox.height), 0); cv::ellipse(mask, bounding, cv::Scalar(255), -1, cv::LINE_4); From 646dc76787b59d1bf7d4f3c3b720016cc527b73e Mon Sep 17 00:00:00 2001 From: Dorson Tang Date: Tue, 4 Aug 2026 17:20:41 -0700 Subject: [PATCH 8/8] proper arguments for cv::resize --- src/modules/opencv/filter_opencv_tracker.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index 365c3124d..2caf65317 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -465,6 +465,8 @@ static int filter_get_image(mlt_frame frame, res, cv::Size(MAX(2, clippedBox.width / blur), MAX(2, clippedBox.height / blur)), + 0, + 0, cv::INTER_NEAREST); cv::resize(res, blurredRoi,