[{"id":11754,"web_url":"https://patchwork.libcamera.org/comment/11754/","msgid":"<20200731154154.GK6218@pendragon.ideasonboard.com>","date":"2020-07-31T15:41:54","subject":"Re: [libcamera-devel] [PATCH v5 00/19] ipu3: rework pipe\n\tconfiuguration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patches.\n\nOn Fri, Jul 31, 2020 at 05:33:01PM +0200, Jacopo Mondi wrote:\n> I have addressed minor comments and added a few more details in comment and\n> documentation here and there.\n> \n> I have simplified a bit the ImgU pipe configuration by removing not-required\n> casts, by making the code a bit less dense, and with a small rename.\n> \n> The diff between v4 and v5 is so minimal I reported the full diff below.\n\nI'll thus review it below :-)\n\n> I tested results against the IPU3 pipe configuration tool by instrumenting\n> a version of it to run on a set of known values and compare the results between\n> its calculation and libcamera:\n> https://jmondi.org/cgit/intel-ipu3-pipe-config/commit/?id=78bc59f8bfe8c14908f612008a62edc621660cf3\n> \n> All patches reviewed but I'm not pushing yet as I would like Kieran's ack, as\n> he's working on JPEG and moving the ground under his feet while developing seems\n> not nice.\n> \n> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp\n> index a3ea3eabe318..cf26980c75f1 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.cpp\n> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp\n> @@ -25,6 +25,14 @@ LOG_DECLARE_CATEGORY(IPU3)\n> \n>  namespace {\n> \n> +/*\n> + * The procedure to calculate the ImgU pipe configuration has been ported\n> + * from the pipe_config.py python script, available at:\n> + * https://github.com/intel/intel-ipu3-pipecfg\n> + * at revision: 61e83f2f7606 (\"Add more information into README\")\n> + */\n> +\n>  static constexpr unsigned int FILTER_H = 4;\n> \n>  static constexpr unsigned int IF_ALIGN_W = 2;\n> @@ -103,10 +111,8 @@ float findScaleFactor(float sf, const std::vector<float> &range,\n> \n>  bool isSameRatio(const Size &in, const Size &out)\n>  {\n> -\tfloat inRatio = static_cast<float>(in.width) /\n> -\t\t\tstatic_cast<float>(in.height);\n> -\tfloat outRatio = static_cast<float>(out.width) /\n> -\t\t\t static_cast<float>(out.height);\n> +\tfloat inRatio = static_cast<float>(in.width) / in.height;\n> +\tfloat outRatio = static_cast<float>(out.width) / out.height;\n> \n>  \tif (std::abs(inRatio - outRatio) > 0.1)\n>  \t\treturn false;\n> @@ -123,16 +129,18 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \tfloat bdsHeight;\n> \n>  \tif (!isSameRatio(pipe->input, gdc)) {\n> -\t\tbool found = false;\n> -\t\tfloat estIFHeight = static_cast<float>(iif.width *  gdc.height) /\n> +\t\tfloat estIFHeight = (iif.width * gdc.height) /\n>  \t\t\t\t    static_cast<float>(gdc.width);\n>  \t\testIFHeight = utils::clamp<float>(estIFHeight, minIFHeight, iif.height);\n> +\t\tbool found = false;\n> +\n>  \t\tifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H);\n> -\t\twhile (ifHeight >= minIFHeight &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> -\t\t\tbdsHeight = static_cast<float>(ifHeight) / bdsSF;\n> +\t\twhile (ifHeight >= minIFHeight && ifHeight / bdsSF >= minBDSHeight) {\n> +\n> +\t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\t\tif (!(bdsIntHeight % BDS_ALIGN_H)) {\n>  \t\t\t\t\tfound = true;\n>  \t\t\t\t\tbreak;\n> @@ -143,11 +151,12 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \t\t}\n> \n>  \t\tifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H);\n> -\t\twhile (ifHeight <= iif.height &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> -\t\t\tbdsHeight = static_cast<float>(ifHeight) / bdsSF;\n> +\t\twhile (ifHeight <= iif.height && ifHeight / bdsSF >= minBDSHeight) {\n> +\n> +\t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\t\tif (!(bdsIntHeight % BDS_ALIGN_H)) {\n>  \t\t\t\t\tfound = true;\n>  \t\t\t\t\tbreak;\n> @@ -159,14 +168,15 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n> \n>  \t\tif (found) {\n>  \t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\tpipeConfigs.push_back({ bdsSF, { iif.width, ifHeight },\n>  \t\t\t\t\t\t{ bdsWidth, bdsIntHeight }, gdc });\n>  \t\t\treturn;\n>  \t\t}\n>  \t} else {\n>  \t\tifHeight = utils::alignUp(iif.height, IF_ALIGN_H);\n> -\t\twhile (ifHeight > minIFHeight &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> +\t\twhile (ifHeight > minIFHeight && ifHeight / bdsSF >= minBDSHeight) {\n> +\n>  \t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(ifHeight, 1.0) == 0 && std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> @@ -183,8 +193,7 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \t}\n>  }\n> \n> -void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc,\n> -\t\t  float bdsSF)\n> +void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc, float bdsSF)\n>  {\n>  \tunsigned int minBDSWidth = gdc.width + FILTER_H * 2;\n> \n> @@ -218,15 +227,14 @@ void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc,\n>  Size calculateGDC(ImgUDevice::Pipe *pipe)\n>  {\n>  \tconst Size &in = pipe->input;\n> -\tconst Size &main = pipe->output;\n> +\tconst Size &main = pipe->main;\n>  \tconst Size &vf = pipe->viewfinder;\n>  \tSize gdc;\n> \n>  \tif (!vf.isNull()) {\n>  \t\tgdc.width = main.width;\n> \n> -\t\tfloat ratio = static_cast<float>(main.width * vf.height) /\n> -\t\t\t      static_cast<float>(vf.width);\n> +\t\tfloat ratio = (main.width * vf.height) / static_cast<float>(vf.width);\n>  \t\tgdc.height = std::max(static_cast<float>(main.height), ratio);\n> \n>  \t\treturn gdc;\n> @@ -237,14 +245,13 @@ Size calculateGDC(ImgUDevice::Pipe *pipe)\n>  \t\treturn gdc;\n>  \t}\n> \n> -\tfloat totalSF = static_cast<float>(in.width) /\n> -\t\t\tstatic_cast<float>(main.width);\n> +\tfloat totalSF = static_cast<float>(in.width) / main.width;\n>  \tfloat bdsSF = totalSF > 2 ? 2 : 1;\n>  \tfloat yuvSF = totalSF / bdsSF;\n>  \tfloat sf = findScaleFactor(yuvSF, gdcScalingFactors);\n> \n> -\tgdc.width = static_cast<float>(main.width) * sf;\n> -\tgdc.height = static_cast<float>(main.height) * sf;\n> +\tgdc.width = main.width * sf;\n> +\tgdc.height = main.height * sf;\n> \n>  \treturn gdc;\n>  }\n> @@ -259,6 +266,7 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)\n>  \tfloat ifCropH = static_cast<float>(in.height - pipe.iif.height);\n>  \tfloat gdcCropW = static_cast<float>(pipe.bds.width - pipe.gdc.width) * pipe.bds_sf;\n>  \tfloat gdcCropH = static_cast<float>(pipe.bds.height - pipe.gdc.height) * pipe.bds_sf;\n> +\n>  \tfov.w = (inW - (ifCropW + gdcCropW)) / inW;\n>  \tfov.h = (inH - (ifCropH + gdcCropH)) / inH;\n> \n> @@ -304,11 +312,11 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)\n>   * \\var Pipe::input\n>   * \\brief The input image size\n>   *\n> - * \\var Pipe::output\n> + * \\var Pipe::main\n>   * \\brief The requested main output size\n>   *\n>   * \\var Pipe::viewfinder\n> - * \\brief The requested viewfinder size\n> + * \\brief The requested viewfinder output size\n>   */\n> \n>  /**\n> @@ -378,7 +386,7 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)\n> \n>  \tLOG(IPU3, Debug) << \"Calculating pipe configuration for: \";\n>  \tLOG(IPU3, Debug) << \"input: \" << pipe->input.toString();\n> -\tLOG(IPU3, Debug) << \"main: \" << pipe->output.toString();\n> +\tLOG(IPU3, Debug) << \"main: \" << pipe->main.toString();\n>  \tLOG(IPU3, Debug) << \"vf: \" << pipe->viewfinder.toString();\n> \n>  \tconst Size &in = pipe->input;\n> @@ -387,9 +395,9 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)\n>  \tunsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W);\n>  \tunsigned int ifHeight = in.height;\n>  \tunsigned int minIfWidth = in.width - IF_CROP_MAX_W;\n> -\tfloat bdsSF = static_cast<float>(in.width) /\n> -\t\t      static_cast<float>(gdc.width);\n> +\tfloat bdsSF = static_cast<float>(in.width) / gdc.width;\n>  \tfloat sf = findScaleFactor(bdsSF, bdsScalingFactors, true);\n> +\n>  \twhile (ifWidth >= minIfWidth) {\n>  \t\tSize iif{ ifWidth, ifHeight };\n>  \t\tcalculateBDS(pipe, iif, gdc, sf);\n> diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h\n> index ff8dab7d645c..c73ac5a5a37c 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.h\n> +++ b/src/libcamera/pipeline/ipu3/imgu.h\n> @@ -37,7 +37,7 @@ public:\n> \n>  \tstruct Pipe {\n>  \t\tSize input;\n> -\t\tSize output;\n> +\t\tSize main;\n>  \t\tSize viewfinder;\n>  \t};\n> \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 06afc7d79dac..161a88da8497 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -225,11 +225,12 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\t\t * margins from the CIO2 output frame size.\n>  \t\t\t *\n>  \t\t\t * The ImgU outputs needs to be strictly smaller than\n> -\t\t\t * the CIO2 output frame and rounded down to 64\n> -\t\t\t * pixels in width and 32 pixels in height. This comes\n> -\t\t\t * from inspecting the pipe configuration script results\n> -\t\t\t * and the available suggested configurations in the\n> -\t\t\t * ChromeOS BSP .xml camera tuning files.\n> +\t\t\t * the CIO2 output frame and rounded down to 64 pixels\n> +\t\t\t * in width and 32 pixels in height. This assumption\n> +\t\t\t * comes from inspecting the pipe configuration script\n> +\t\t\t * results and the available suggested configurations in\n> +\t\t\t * the ChromeOS BSP .xml camera tuning files and shall\n> +\t\t\t * be validated.\n>  \t\t\t *\n>  \t\t\t * \\todo Clarify what are the hardware constraints\n>  \t\t\t * that require this alignements, if any. It might\n> @@ -267,9 +268,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\t\t\tcfg->setStream(const_cast<Stream *>(&data_->outStream_));\n>  \t\t\t\tmainOutputAvailable = false;\n> \n> -\t\t\t\tpipe.output = cfg->size;\n> +\t\t\t\tpipe.main = cfg->size;\n>  \t\t\t\tif (yuvCount == 1)\n> -\t\t\t\t\tpipe.viewfinder = pipe.output;\n> +\t\t\t\t\tpipe.viewfinder = pipe.main;\n> \n>  \t\t\t\tLOG(IPU3, Debug) << \"Assigned \" << cfg->toString()\n>  \t\t\t\t\t\t << \" to the main output\";\n> @@ -333,8 +334,8 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \t\t\t * to the ImgU  maximum output size) and aligned down to\n>  \t\t\t * the required frame margin.\n>  \t\t\t *\n> -\t\t\t * The alignment constraints should be clarified\n> -\t\t\t * as per the todo item in validate().\n> +\t\t\t * \\todo Clarify the alignment constraints as exaplained\n\ns/exaplained/explained/\n\n> +\t\t\t * in validate()\n>  \t\t\t */\n>  \t\t\tsize = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE);\n>  \t\t\tsize.width = utils::alignDown(size.width - 1,\n> \n> Jacopo Mondi (19):\n>   libcamera: ipu3: Rename mbusCodesToInfo\n>   libcamera: utils: Add alignUp and alignDown functions\n>   libcamera: geometry: Add isNull() function to Rectangle class\n>   libcamera: ipu3: Remove streams from generateConfiguration\n>   libcamera: ipu3: Make sure the config is valid\n>   libcamera: ipu3: cio2: Report format and sizes\n>   libcamera: ipu3: Do not overwrite StreamConfiguration\n>   libcamera: ipu3: Report StreamFormats\n>   libcamera: ipu3: Remove initialization of Size\n>   libcamera: ipu3: Validate the stream combination\n>   libcamera: camera: Zero streams before validate()\n>   libcamera: ipu3: cio2: Add a const sensor() method\n>   libcamera: ipu3: Adjust and assign streams in validate()\n>   libcamera: ipu3: Remove streams from IPU3CameraConfiguration\n>   libcamera: ipu3: Remove camera_ from IPU3CameraConfiguration\n>   libcamera: ipu3: imgu: Calculate ImgU pipe configuration\n>   libcamera: ipu3: Validate the pipe configuration\n>   libcamera: ipu3: Configure ImgU with the computed parameters\n>   libcamera: ipu3: imgu: Rename configureInput()\n> \n>  include/libcamera/geometry.h         |   1 +\n>  include/libcamera/internal/utils.h   |  10 +\n>  src/libcamera/camera.cpp             |   4 +-\n>  src/libcamera/geometry.cpp           |   6 +\n>  src/libcamera/pipeline/ipu3/cio2.cpp |  54 +++-\n>  src/libcamera/pipeline/ipu3/cio2.h   |   6 +\n>  src/libcamera/pipeline/ipu3/imgu.    |   0\n>  src/libcamera/pipeline/ipu3/imgu.cpp | 386 +++++++++++++++++++++++-\n>  src/libcamera/pipeline/ipu3/imgu.h   |  22 +-\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 424 +++++++++++++--------------\n>  src/libcamera/utils.cpp              |  16 +\n>  test/geometry.cpp                    |  14 +\n>  test/utils.cpp                       |  11 +\n>  13 files changed, 714 insertions(+), 240 deletions(-)\n>  create mode 100644 src/libcamera/pipeline/ipu3/imgu.\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9A39CBD878\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 31 Jul 2020 15:42:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2745B61A14;\n\tFri, 31 Jul 2020 17:42:06 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C036660398\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 31 Jul 2020 17:42:04 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3899153C;\n\tFri, 31 Jul 2020 17:42:04 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"RW4amVd9\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1596210124;\n\tbh=BpF/+XfT8KUbJIOcIppnH/2L5NChIE+6W2l5zFTM4ec=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=RW4amVd9MdTAuYfwtvsHiOSxUoi6Fxmksi3M/qPj76js6IiP25uCZdNca7LhIfka5\n\tyuLPvq0igNpkONhRMy3g4IvufWBZokkox8moGKiITiWlyJNKZbST9tFhqQW7Q0H+WC\n\tfZX+HZQf/48acK0Fx18o/jKINaM9jxhP2N+dqhd0=","Date":"Fri, 31 Jul 2020 18:41:54 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20200731154154.GK6218@pendragon.ideasonboard.com>","References":"<20200731153320.58107-1-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200731153320.58107-1-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH v5 00/19] ipu3: rework pipe\n\tconfiuguration","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11788,"web_url":"https://patchwork.libcamera.org/comment/11788/","msgid":"<a01748af-6ba7-c8e9-e5e4-820b8a565585@ideasonboard.com>","date":"2020-08-03T09:20:19","subject":"Re: [libcamera-devel] [PATCH v5 00/19] ipu3: rework pipe\n\tconfiuguration","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Jacopo,\n\nI've gone through this series quickly, and my work is based upon it.\n\nYou already seem to have two RB tags for each patch, so rather than do a\ndetailed review, I'll just say \"Acked-by: Kieran Bingham\n<kieran.bingham@ideasonboard.com>\" for the whole series, and I'm happy\nto get this in and keep pushing forwards :-)\n\n--\nKieran\n\n\nOn 31/07/2020 16:33, Jacopo Mondi wrote:\n> I have addressed minor comments and added a few more details in comment and\n> documentation here and there.\n> \n> I have simplified a bit the ImgU pipe configuration by removing not-required\n> casts, by making the code a bit less dense, and with a small rename.\n> \n> The diff between v4 and v5 is so minimal I reported the full diff below.\n> \n> I tested results against the IPU3 pipe configuration tool by instrumenting\n> a version of it to run on a set of known values and compare the results between\n> its calculation and libcamera:\n> https://jmondi.org/cgit/intel-ipu3-pipe-config/commit/?id=78bc59f8bfe8c14908f612008a62edc621660cf3\n> \n> All patches reviewed but I'm not pushing yet as I would like Kieran's ack, as\n> he's working on JPEG and moving the ground under his feet while developing seems\n> not nice.\n> \n> diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp\n> index a3ea3eabe318..cf26980c75f1 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.cpp\n> +++ b/src/libcamera/pipeline/ipu3/imgu.cpp\n> @@ -25,6 +25,14 @@ LOG_DECLARE_CATEGORY(IPU3)\n> \n>  namespace {\n> \n> +/*\n> + * The procedure to calculate the ImgU pipe configuration has been ported\n> + * from the pipe_config.py python script, available at:\n> + * https://github.com/intel/intel-ipu3-pipecfg\n> + * at revision: 61e83f2f7606 (\"Add more information into README\")\n> + */\n> +\n>  static constexpr unsigned int FILTER_H = 4;\n> \n>  static constexpr unsigned int IF_ALIGN_W = 2;\n> @@ -103,10 +111,8 @@ float findScaleFactor(float sf, const std::vector<float> &range,\n> \n>  bool isSameRatio(const Size &in, const Size &out)\n>  {\n> -\tfloat inRatio = static_cast<float>(in.width) /\n> -\t\t\tstatic_cast<float>(in.height);\n> -\tfloat outRatio = static_cast<float>(out.width) /\n> -\t\t\t static_cast<float>(out.height);\n> +\tfloat inRatio = static_cast<float>(in.width) / in.height;\n> +\tfloat outRatio = static_cast<float>(out.width) / out.height;\n> \n>  \tif (std::abs(inRatio - outRatio) > 0.1)\n>  \t\treturn false;\n> @@ -123,16 +129,18 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \tfloat bdsHeight;\n> \n>  \tif (!isSameRatio(pipe->input, gdc)) {\n> -\t\tbool found = false;\n> -\t\tfloat estIFHeight = static_cast<float>(iif.width *  gdc.height) /\n> +\t\tfloat estIFHeight = (iif.width * gdc.height) /\n>  \t\t\t\t    static_cast<float>(gdc.width);\n>  \t\testIFHeight = utils::clamp<float>(estIFHeight, minIFHeight, iif.height);\n> +\t\tbool found = false;\n> +\n>  \t\tifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H);\n> -\t\twhile (ifHeight >= minIFHeight &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> -\t\t\tbdsHeight = static_cast<float>(ifHeight) / bdsSF;\n> +\t\twhile (ifHeight >= minIFHeight && ifHeight / bdsSF >= minBDSHeight) {\n> +\n> +\t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\t\tif (!(bdsIntHeight % BDS_ALIGN_H)) {\n>  \t\t\t\t\tfound = true;\n>  \t\t\t\t\tbreak;\n> @@ -143,11 +151,12 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \t\t}\n> \n>  \t\tifHeight = utils::alignUp(estIFHeight, IF_ALIGN_H);\n> -\t\twhile (ifHeight <= iif.height &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> -\t\t\tbdsHeight = static_cast<float>(ifHeight) / bdsSF;\n> +\t\twhile (ifHeight <= iif.height && ifHeight / bdsSF >= minBDSHeight) {\n> +\n> +\t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\t\tif (!(bdsIntHeight % BDS_ALIGN_H)) {\n>  \t\t\t\t\tfound = true;\n>  \t\t\t\t\tbreak;\n> @@ -159,14 +168,15 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n> \n>  \t\tif (found) {\n>  \t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> +\n>  \t\t\tpipeConfigs.push_back({ bdsSF, { iif.width, ifHeight },\n>  \t\t\t\t\t\t{ bdsWidth, bdsIntHeight }, gdc });\n>  \t\t\treturn;\n>  \t\t}\n>  \t} else {\n>  \t\tifHeight = utils::alignUp(iif.height, IF_ALIGN_H);\n> -\t\twhile (ifHeight > minIFHeight &&\n> -\t\t       static_cast<float>(ifHeight) / bdsSF >= minBDSHeight) {\n> +\t\twhile (ifHeight > minIFHeight && ifHeight / bdsSF >= minBDSHeight) {\n> +\n>  \t\t\tbdsHeight = ifHeight / bdsSF;\n>  \t\t\tif (std::fmod(ifHeight, 1.0) == 0 && std::fmod(bdsHeight, 1.0) == 0) {\n>  \t\t\t\tunsigned int bdsIntHeight = static_cast<unsigned int>(bdsHeight);\n> @@ -183,8 +193,7 @@ void calculateBDSHeight(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc\n>  \t}\n>  }\n> \n> -void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc,\n> -\t\t  float bdsSF)\n> +void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc, float bdsSF)\n>  {\n>  \tunsigned int minBDSWidth = gdc.width + FILTER_H * 2;\n> \n> @@ -218,15 +227,14 @@ void calculateBDS(ImgUDevice::Pipe *pipe, const Size &iif, const Size &gdc,\n>  Size calculateGDC(ImgUDevice::Pipe *pipe)\n>  {\n>  \tconst Size &in = pipe->input;\n> -\tconst Size &main = pipe->output;\n> +\tconst Size &main = pipe->main;\n>  \tconst Size &vf = pipe->viewfinder;\n>  \tSize gdc;\n> \n>  \tif (!vf.isNull()) {\n>  \t\tgdc.width = main.width;\n> \n> -\t\tfloat ratio = static_cast<float>(main.width * vf.height) /\n> -\t\t\t      static_cast<float>(vf.width);\n> +\t\tfloat ratio = (main.width * vf.height) / static_cast<float>(vf.width);\n>  \t\tgdc.height = std::max(static_cast<float>(main.height), ratio);\n> \n>  \t\treturn gdc;\n> @@ -237,14 +245,13 @@ Size calculateGDC(ImgUDevice::Pipe *pipe)\n>  \t\treturn gdc;\n>  \t}\n> \n> -\tfloat totalSF = static_cast<float>(in.width) /\n> -\t\t\tstatic_cast<float>(main.width);\n> +\tfloat totalSF = static_cast<float>(in.width) / main.width;\n>  \tfloat bdsSF = totalSF > 2 ? 2 : 1;\n>  \tfloat yuvSF = totalSF / bdsSF;\n>  \tfloat sf = findScaleFactor(yuvSF, gdcScalingFactors);\n> \n> -\tgdc.width = static_cast<float>(main.width) * sf;\n> -\tgdc.height = static_cast<float>(main.height) * sf;\n> +\tgdc.width = main.width * sf;\n> +\tgdc.height = main.height * sf;\n> \n>  \treturn gdc;\n>  }\n> @@ -259,6 +266,7 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)\n>  \tfloat ifCropH = static_cast<float>(in.height - pipe.iif.height);\n>  \tfloat gdcCropW = static_cast<float>(pipe.bds.width - pipe.gdc.width) * pipe.bds_sf;\n>  \tfloat gdcCropH = static_cast<float>(pipe.bds.height - pipe.gdc.height) * pipe.bds_sf;\n> +\n>  \tfov.w = (inW - (ifCropW + gdcCropW)) / inW;\n>  \tfov.h = (inH - (ifCropH + gdcCropH)) / inH;\n> \n> @@ -304,11 +312,11 @@ FOV calcFOV(const Size &in, const ImgUDevice::PipeConfig &pipe)\n>   * \\var Pipe::input\n>   * \\brief The input image size\n>   *\n> - * \\var Pipe::output\n> + * \\var Pipe::main\n>   * \\brief The requested main output size\n>   *\n>   * \\var Pipe::viewfinder\n> - * \\brief The requested viewfinder size\n> + * \\brief The requested viewfinder output size\n>   */\n> \n>  /**\n> @@ -378,7 +386,7 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)\n> \n>  \tLOG(IPU3, Debug) << \"Calculating pipe configuration for: \";\n>  \tLOG(IPU3, Debug) << \"input: \" << pipe->input.toString();\n> -\tLOG(IPU3, Debug) << \"main: \" << pipe->output.toString();\n> +\tLOG(IPU3, Debug) << \"main: \" << pipe->main.toString();\n>  \tLOG(IPU3, Debug) << \"vf: \" << pipe->viewfinder.toString();\n> \n>  \tconst Size &in = pipe->input;\n> @@ -387,9 +395,9 @@ ImgUDevice::PipeConfig ImgUDevice::calculatePipeConfig(Pipe *pipe)\n>  \tunsigned int ifWidth = utils::alignUp(in.width, IF_ALIGN_W);\n>  \tunsigned int ifHeight = in.height;\n>  \tunsigned int minIfWidth = in.width - IF_CROP_MAX_W;\n> -\tfloat bdsSF = static_cast<float>(in.width) /\n> -\t\t      static_cast<float>(gdc.width);\n> +\tfloat bdsSF = static_cast<float>(in.width) / gdc.width;\n>  \tfloat sf = findScaleFactor(bdsSF, bdsScalingFactors, true);\n> +\n>  \twhile (ifWidth >= minIfWidth) {\n>  \t\tSize iif{ ifWidth, ifHeight };\n>  \t\tcalculateBDS(pipe, iif, gdc, sf);\n> diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h\n> index ff8dab7d645c..c73ac5a5a37c 100644\n> --- a/src/libcamera/pipeline/ipu3/imgu.h\n> +++ b/src/libcamera/pipeline/ipu3/imgu.h\n> @@ -37,7 +37,7 @@ public:\n> \n>  \tstruct Pipe {\n>  \t\tSize input;\n> -\t\tSize output;\n> +\t\tSize main;\n>  \t\tSize viewfinder;\n>  \t};\n> \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 06afc7d79dac..161a88da8497 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -225,11 +225,12 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\t\t * margins from the CIO2 output frame size.\n>  \t\t\t *\n>  \t\t\t * The ImgU outputs needs to be strictly smaller than\n> -\t\t\t * the CIO2 output frame and rounded down to 64\n> -\t\t\t * pixels in width and 32 pixels in height. This comes\n> -\t\t\t * from inspecting the pipe configuration script results\n> -\t\t\t * and the available suggested configurations in the\n> -\t\t\t * ChromeOS BSP .xml camera tuning files.\n> +\t\t\t * the CIO2 output frame and rounded down to 64 pixels\n> +\t\t\t * in width and 32 pixels in height. This assumption\n> +\t\t\t * comes from inspecting the pipe configuration script\n> +\t\t\t * results and the available suggested configurations in\n> +\t\t\t * the ChromeOS BSP .xml camera tuning files and shall\n> +\t\t\t * be validated.\n>  \t\t\t *\n>  \t\t\t * \\todo Clarify what are the hardware constraints\n>  \t\t\t * that require this alignements, if any. It might\n> @@ -267,9 +268,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\t\t\tcfg->setStream(const_cast<Stream *>(&data_->outStream_));\n>  \t\t\t\tmainOutputAvailable = false;\n> \n> -\t\t\t\tpipe.output = cfg->size;\n> +\t\t\t\tpipe.main = cfg->size;\n>  \t\t\t\tif (yuvCount == 1)\n> -\t\t\t\t\tpipe.viewfinder = pipe.output;\n> +\t\t\t\t\tpipe.viewfinder = pipe.main;\n> \n>  \t\t\t\tLOG(IPU3, Debug) << \"Assigned \" << cfg->toString()\n>  \t\t\t\t\t\t << \" to the main output\";\n> @@ -333,8 +334,8 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \t\t\t * to the ImgU  maximum output size) and aligned down to\n>  \t\t\t * the required frame margin.\n>  \t\t\t *\n> -\t\t\t * The alignment constraints should be clarified\n> -\t\t\t * as per the todo item in validate().\n> +\t\t\t * \\todo Clarify the alignment constraints as exaplained\n> +\t\t\t * in validate()\n>  \t\t\t */\n>  \t\t\tsize = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE);\n>  \t\t\tsize.width = utils::alignDown(size.width - 1,\n> \n> Thanks\n>    j\n> \n> Jacopo Mondi (19):\n>   libcamera: ipu3: Rename mbusCodesToInfo\n>   libcamera: utils: Add alignUp and alignDown functions\n>   libcamera: geometry: Add isNull() function to Rectangle class\n>   libcamera: ipu3: Remove streams from generateConfiguration\n>   libcamera: ipu3: Make sure the config is valid\n>   libcamera: ipu3: cio2: Report format and sizes\n>   libcamera: ipu3: Do not overwrite StreamConfiguration\n>   libcamera: ipu3: Report StreamFormats\n>   libcamera: ipu3: Remove initialization of Size\n>   libcamera: ipu3: Validate the stream combination\n>   libcamera: camera: Zero streams before validate()\n>   libcamera: ipu3: cio2: Add a const sensor() method\n>   libcamera: ipu3: Adjust and assign streams in validate()\n>   libcamera: ipu3: Remove streams from IPU3CameraConfiguration\n>   libcamera: ipu3: Remove camera_ from IPU3CameraConfiguration\n>   libcamera: ipu3: imgu: Calculate ImgU pipe configuration\n>   libcamera: ipu3: Validate the pipe configuration\n>   libcamera: ipu3: Configure ImgU with the computed parameters\n>   libcamera: ipu3: imgu: Rename configureInput()\n> \n>  include/libcamera/geometry.h         |   1 +\n>  include/libcamera/internal/utils.h   |  10 +\n>  src/libcamera/camera.cpp             |   4 +-\n>  src/libcamera/geometry.cpp           |   6 +\n>  src/libcamera/pipeline/ipu3/cio2.cpp |  54 +++-\n>  src/libcamera/pipeline/ipu3/cio2.h   |   6 +\n>  src/libcamera/pipeline/ipu3/imgu.    |   0\n>  src/libcamera/pipeline/ipu3/imgu.cpp | 386 +++++++++++++++++++++++-\n>  src/libcamera/pipeline/ipu3/imgu.h   |  22 +-\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 424 +++++++++++++--------------\n>  src/libcamera/utils.cpp              |  16 +\n>  test/geometry.cpp                    |  14 +\n>  test/utils.cpp                       |  11 +\n>  13 files changed, 714 insertions(+), 240 deletions(-)\n>  create mode 100644 src/libcamera/pipeline/ipu3/imgu.\n> \n> --\n> 2.27.0\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id D58BEBD86F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  3 Aug 2020 09:20:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6EB0561820;\n\tMon,  3 Aug 2020 11:20:24 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1ADDE60391\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  3 Aug 2020 11:20:23 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 806C3543;\n\tMon,  3 Aug 2020 11:20:22 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jreQ6A7b\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1596446422;\n\tbh=feQ4G2CODpiSkeoT2Ng1wkf2HByptXl0XbxP7wPwP04=;\n\th=Reply-To:Subject:To:References:From:Date:In-Reply-To:From;\n\tb=jreQ6A7bAadCc8hOgF7FZxylFDPtpbCqM5wMHzMoyjXZqnqVQGQZLLlreq5yabeIU\n\tWxIS/WM+pvvb1cM+EWf8UTlQzUUPrOQLdpC9ZAetSwIfD9TwRIUz326y+ALMNns8OV\n\tWOSzyIf9BfmO5nJ9ypIvHCoDTp4vjJruDVuce+JU=","To":"Jacopo Mondi <jacopo@jmondi.org>, libcamera-devel@lists.libcamera.org","References":"<20200731153320.58107-1-jacopo@jmondi.org>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tWZw01QYHU/GUV/zHJSFk","Organization":"Ideas on Board","Message-ID":"<a01748af-6ba7-c8e9-e5e4-820b8a565585@ideasonboard.com>","Date":"Mon, 3 Aug 2020 10:20:19 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101\n\tThunderbird/68.10.0","MIME-Version":"1.0","In-Reply-To":"<20200731153320.58107-1-jacopo@jmondi.org>","Content-Language":"en-GB","Subject":"Re: [libcamera-devel] [PATCH v5 00/19] ipu3: rework pipe\n\tconfiuguration","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Reply-To":"kieran.bingham@ideasonboard.com","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]