[libcamera-devel,v3,2/8] libcamera: ipu3: imgu: Filter resolutions < IF_CROP_MAX
diff mbox series

Message ID 20210513152116.17666-3-jacopo@jmondi.org
State Accepted
Commit 1da35058ec65e2ec17c788fd0aad7b80a269b469
Delegated to: Jacopo Mondi
Headers show
Series
  • ipu3: imgu: Improve ImgU calculation procedure
Related show

Commit Message

Jacopo Mondi May 13, 2021, 3:21 p.m. UTC
As reported in https://bugs.libcamera.org/show_bug.cgi?id=32
allowing resolutions < IF_CROP_MAX leads to a not manageable number
configurations to be tested, slowing down the ImgU pipe configuration
to a point which is not acceptable for production devices.

Filter all resolutions < IF_CROP_MAX to maintain the run-time complexity
acceptable and remove the safety check that was meant to avoid overflows
when computing the IF rectangle sizes.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=32
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/imgu.cpp | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

Comments

Hirokazu Honda May 17, 2021, 3:57 a.m. UTC | #1
Hi Jacopo, thank you for the patch.

On Fri, May 14, 2021 at 12:20 AM Jacopo Mondi <jacopo@jmondi.org> wrote:

> As reported in https://bugs.libcamera.org/show_bug.cgi?id=32
> allowing resolutions < IF_CROP_MAX leads to a not manageable number
> configurations to be tested, slowing down the ImgU pipe configuration
> to a point which is not acceptable for production devices.
>
> Filter all resolutions < IF_CROP_MAX to maintain the run-time complexity
> acceptable and remove the safety check that was meant to avoid overflows
> when computing the IF rectangle sizes.
>
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=32
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
>

Reviewed-by: Hirokazu Honda <hiroh@chromium.org>

> ---
>  src/libcamera/pipeline/ipu3/imgu.cpp | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp
> b/src/libcamera/pipeline/ipu3/imgu.cpp
> index acc625ab0fac..f25f14a71e9e 100644
> --- a/src/libcamera/pipeline/ipu3/imgu.cpp
> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp
> @@ -392,6 +392,17 @@ ImgUDevice::PipeConfig
> ImgUDevice::calculatePipeConfig(Pipe *pipe)
>         LOG(IPU3, Debug) << "vf: " << pipe->viewfinder.toString();
>
>         const Size &in = pipe->input;
> +
> +       /*
> +        * \todo Filter out all resolutions < IF_CROP_MAX.
> +        * See https://bugs.libcamera.org/show_bug.cgi?id=32
> +        */
> +       if (in.width < IF_CROP_MAX_W || in.height < IF_CROP_MAX_H) {
> +               LOG(IPU3, Error) << "Input resolution " << in.toString()
> +                                << " not supported";
> +               return {};
> +       }
> +
>         Size gdc = calculateGDC(pipe);
>
>         float bdsSF = static_cast<float>(in.width) / gdc.width;
> @@ -400,10 +411,8 @@ ImgUDevice::PipeConfig
> ImgUDevice::calculatePipeConfig(Pipe *pipe)
>         /* Populate the configurations vector by scaling width and height.
> */
>         unsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
>         unsigned int ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
> -       unsigned int minIfWidth = std::min(IF_ALIGN_W,
> -                                          in.width - IF_CROP_MAX_W);
> -       unsigned int minIfHeight = std::min(IF_ALIGN_H,
> -                                           in.height - IF_CROP_MAX_H);
> +       unsigned int minIfWidth = in.width - IF_CROP_MAX_W;
> +       unsigned int minIfHeight = in.height - IF_CROP_MAX_H;
>         while (ifWidth >= minIfWidth) {
>                 while (ifHeight >= minIfHeight) {
>                         Size iif{ ifWidth, ifHeight };
> @@ -417,8 +426,8 @@ ImgUDevice::PipeConfig
> ImgUDevice::calculatePipeConfig(Pipe *pipe)
>         /* Repeat search by scaling width first. */
>         ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
>         ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
> -       minIfWidth = std::min(IF_ALIGN_W, in.width - IF_CROP_MAX_W);
> -       minIfHeight = std::min(IF_ALIGN_H, in.height - IF_CROP_MAX_H);
> +       minIfWidth = in.width - IF_CROP_MAX_W;
> +       minIfHeight = in.height - IF_CROP_MAX_H;
>         while (ifHeight >= minIfHeight) {
>                 /*
>                  * \todo This procedure is probably broken:
> --
> 2.31.1
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
>
Jean-Michel Hautbois May 20, 2021, 8:43 a.m. UTC | #2
Hi Jacopo,

On 13/05/2021 17:21, Jacopo Mondi wrote:
> As reported in https://bugs.libcamera.org/show_bug.cgi?id=32
> allowing resolutions < IF_CROP_MAX leads to a not manageable number
> configurations to be tested, slowing down the ImgU pipe configuration
> to a point which is not acceptable for production devices.
> 
> Filter all resolutions < IF_CROP_MAX to maintain the run-time complexity
> acceptable and remove the safety check that was meant to avoid overflows
> when computing the IF rectangle sizes.
> 
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=32
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
> ---
>  src/libcamera/pipeline/ipu3/imgu.cpp | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp
> index acc625ab0fac..f25f14a71e9e 100644
> --- a/src/libcamera/pipeline/ipu3/imgu.cpp
> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp
> @@ -392,6 +392,17 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
>  	LOG(IPU3, Debug) << "vf: " << pipe->viewfinder.toString();
>  
>  	const Size &in = pipe->input;
> +
> +	/*
> +	 * \todo Filter out all resolutions < IF_CROP_MAX.
> +	 * See https://bugs.libcamera.org/show_bug.cgi?id=32
> +	 */
> +	if (in.width < IF_CROP_MAX_W || in.height < IF_CROP_MAX_H) {
> +		LOG(IPU3, Error) << "Input resolution " << in.toString()
> +				 << " not supported";
> +		return {};
> +	}
> +
>  	Size gdc = calculateGDC(pipe);
>  
>  	float bdsSF = static_cast<float>(in.width) / gdc.width;
> @@ -400,10 +411,8 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
>  	/* Populate the configurations vector by scaling width and height. */
>  	unsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
>  	unsigned int ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
> -	unsigned int minIfWidth = std::min(IF_ALIGN_W,
> -					   in.width - IF_CROP_MAX_W);
> -	unsigned int minIfHeight = std::min(IF_ALIGN_H,
> -					    in.height - IF_CROP_MAX_H);
> +	unsigned int minIfWidth = in.width - IF_CROP_MAX_W;
> +	unsigned int minIfHeight = in.height - IF_CROP_MAX_H;
>  	while (ifWidth >= minIfWidth) {
>  		while (ifHeight >= minIfHeight) {
>  			Size iif{ ifWidth, ifHeight };
> @@ -417,8 +426,8 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
>  	/* Repeat search by scaling width first. */
>  	ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
>  	ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
> -	minIfWidth = std::min(IF_ALIGN_W, in.width - IF_CROP_MAX_W);
> -	minIfHeight = std::min(IF_ALIGN_H, in.height - IF_CROP_MAX_H);
> +	minIfWidth = in.width - IF_CROP_MAX_W;
> +	minIfHeight = in.height - IF_CROP_MAX_H;
>  	while (ifHeight >= minIfHeight) {
>  		/*
>  		 * \todo This procedure is probably broken:
>

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp
index acc625ab0fac..f25f14a71e9e 100644
--- a/src/libcamera/pipeline/ipu3/imgu.cpp
+++ b/src/libcamera/pipeline/ipu3/imgu.cpp
@@ -392,6 +392,17 @@  ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
 	LOG(IPU3, Debug) << "vf: " << pipe->viewfinder.toString();
 
 	const Size &in = pipe->input;
+
+	/*
+	 * \todo Filter out all resolutions < IF_CROP_MAX.
+	 * See https://bugs.libcamera.org/show_bug.cgi?id=32
+	 */
+	if (in.width < IF_CROP_MAX_W || in.height < IF_CROP_MAX_H) {
+		LOG(IPU3, Error) << "Input resolution " << in.toString()
+				 << " not supported";
+		return {};
+	}
+
 	Size gdc = calculateGDC(pipe);
 
 	float bdsSF = static_cast<float>(in.width) / gdc.width;
@@ -400,10 +411,8 @@  ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
 	/* Populate the configurations vector by scaling width and height. */
 	unsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
 	unsigned int ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
-	unsigned int minIfWidth = std::min(IF_ALIGN_W,
-					   in.width - IF_CROP_MAX_W);
-	unsigned int minIfHeight = std::min(IF_ALIGN_H,
-					    in.height - IF_CROP_MAX_H);
+	unsigned int minIfWidth = in.width - IF_CROP_MAX_W;
+	unsigned int minIfHeight = in.height - IF_CROP_MAX_H;
 	while (ifWidth >= minIfWidth) {
 		while (ifHeight >= minIfHeight) {
 			Size iif{ ifWidth, ifHeight };
@@ -417,8 +426,8 @@  ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)
 	/* Repeat search by scaling width first. */
 	ifWidth = utils::alignUp(in.width, IF_ALIGN_W);
 	ifHeight = utils::alignUp(in.height, IF_ALIGN_H);
-	minIfWidth = std::min(IF_ALIGN_W, in.width - IF_CROP_MAX_W);
-	minIfHeight = std::min(IF_ALIGN_H, in.height - IF_CROP_MAX_H);
+	minIfWidth = in.width - IF_CROP_MAX_W;
+	minIfHeight = in.height - IF_CROP_MAX_H;
 	while (ifHeight >= minIfHeight) {
 		/*
 		 * \todo This procedure is probably broken: