[{"id":31682,"web_url":"https://patchwork.libcamera.org/comment/31682/","msgid":"<172851571567.532453.8003880686390298604@ping.linuxembedded.co.uk>","date":"2024-10-09T23:15:15","subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Hans de Goede (2024-10-09 21:01:10)\n> Add a method to the SwstatsCpu class to process a whole Framebuffer in\n> one go, rather then line by line. This is useful for gathering stats\n> when debayering is not necessary or is not done on the CPU.\n\nI can't see how this is used yet. Is it just something that you would be\nable to directly set up and call on a frame explicitly if desired?\n\nI expect that's possible as it's RFC ... So I think I'll leave this one\nto other soft-isp devs... But I can understand that it could be useful\nfor future development.\n\n--\nKieran\n\n> \n> Signed-off-by: Hans de Goede <hdegoede@redhat.com>\n> ---\n>  src/libcamera/software_isp/swstats_cpu.cpp | 72 ++++++++++++++++++++++\n>  src/libcamera/software_isp/swstats_cpu.h   | 10 +++\n>  2 files changed, 82 insertions(+)\n> \n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index 5e4246a9..117147c2 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -16,6 +16,7 @@\n>  #include <libcamera/stream.h>\n>  \n>  #include \"libcamera/internal/bayer_format.h\"\n> +#include \"libcamera/internal/mapped_framebuffer.h\"\n>  \n>  namespace libcamera {\n>  \n> @@ -363,8 +364,11 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>         BayerFormat bayerFormat =\n>                 BayerFormat::fromPixelFormat(inputCfg.pixelFormat);\n>  \n> +       stride_ = inputCfg.stride;\n> +\n>         if (bayerFormat.packing == BayerFormat::Packing::None &&\n>             setupStandardBayerOrder(bayerFormat.order) == 0) {\n> +               bpp_ = (bayerFormat.bitDepth + 7) & ~7;\n>                 switch (bayerFormat.bitDepth) {\n>                 case 8:\n>                         stats0_ = &SwStatsCpu::statsBGGR8Line0;\n> @@ -385,6 +389,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>                 /* Skip every 3th and 4th line, sample every other 2x2 block */\n>                 ySkipMask_ = 0x02;\n>                 xShift_ = 0;\n> +               bpp_ = 10;\n>  \n>                 switch (bayerFormat.order) {\n>                 case BayerFormat::BGGR:\n> @@ -425,4 +430,71 @@ void SwStatsCpu::setWindow(const Rectangle &window)\n>         window_.height &= ~(patternSize_.height - 1);\n>  }\n>  \n> +void SwStatsCpu::processFrame2(const uint8_t *src)\n> +{\n> +       unsigned int yEnd = window_.y + window_.height;\n> +       const uint8_t *linePointers[3];\n> +\n> +       /* Adjust src to top left corner of the window */\n> +       src += window_.y * stride_ + window_.x * bpp_ / 8;\n> +\n> +       for (unsigned int y = window_.y; y < yEnd; y += 2) {\n> +               if (y & ySkipMask_) {\n> +                       src += stride_ * 2;\n> +                       continue;\n> +               }\n> +\n> +               /* linePointers[0] is not used by any stats0_ functions */\n> +               linePointers[1] = src;\n> +               linePointers[2] = src + stride_;\n> +               (this->*stats0_)(linePointers);\n> +               src += stride_ * 2;\n> +       }\n> +}\n> +\n> +void SwStatsCpu::processFrame4(const uint8_t *src)\n> +{\n> +       const unsigned int yEnd = window_.y + window_.height;\n> +       const uint8_t *linePointers[4];\n> +\n> +       /* Adjust src to top left corner of the window */\n> +       src += window_.y * stride_ + window_.x * bpp_ / 8;\n> +\n> +       for (unsigned int y = window_.y; y < yEnd; y += 4) {\n> +               if (y & ySkipMask_) {\n> +                       src += stride_ * 4;\n> +                       continue;\n> +               }\n> +\n> +               /* linePointers[0] and [1] are not used by 4 line pattern stats0_ functions */\n> +               linePointers[2] = src;\n> +               linePointers[3] = src + stride_;\n> +               (this->*stats0_)(linePointers);\n> +               src += stride_ * 2;\n> +\n> +               linePointers[2] = src;\n> +               linePointers[3] = src + stride_;\n> +               (this->*stats2_)(linePointers);\n> +               src += stride_ * 2;\n> +       }\n> +}\n> +\n> +void SwStatsCpu::processFrame(FrameBuffer *input)\n> +{\n> +       bench_.startFrame();\n> +\n> +       MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +       if (!in.isValid()) {\n> +               LOG(SwStatsCpu, Error) << \"mmap-ing buffer(s) failed\";\n> +               return;\n> +       }\n> +\n> +       if (patternSize_.height == 2)\n> +               processFrame2(in.planes()[0].data());\n> +       else\n> +               processFrame4(in.planes()[0].data());\n> +\n> +       bench_.finishFrame();\n> +}\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/software_isp/swstats_cpu.h b/src/libcamera/software_isp/swstats_cpu.h\n> index 26a2f462..bb178a04 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.h\n> +++ b/src/libcamera/software_isp/swstats_cpu.h\n> @@ -18,9 +18,12 @@\n>  #include <libcamera/geometry.h>\n>  \n>  #include \"libcamera/internal/bayer_format.h\"\n> +#include \"libcamera/internal/framebuffer.h\"\n>  #include \"libcamera/internal/shared_mem_object.h\"\n>  #include \"libcamera/internal/software_isp/swisp_stats.h\"\n>  \n> +#include \"benchmark.h\"\n> +\n>  namespace libcamera {\n>  \n>  class PixelFormat;\n> @@ -42,6 +45,7 @@ public:\n>         void setWindow(const Rectangle &window);\n>         void startFrame();\n>         void finishFrame(uint32_t frame, uint32_t bufferId);\n> +       void processFrame(FrameBuffer *input);\n>  \n>         void processLine0(unsigned int y, const uint8_t *src[])\n>         {\n> @@ -77,6 +81,9 @@ private:\n>         void statsBGGR10PLine0(const uint8_t *src[]);\n>         void statsGBRG10PLine0(const uint8_t *src[]);\n>  \n> +       void processFrame2(const uint8_t *src);\n> +       void processFrame4(const uint8_t *src);\n> +\n>         /* Variables set by configure(), used every line */\n>         statsProcessFn stats0_;\n>         statsProcessFn stats2_;\n> @@ -89,9 +96,12 @@ private:\n>         Size patternSize_;\n>  \n>         unsigned int xShift_;\n> +       unsigned int bpp_; /* Memory used per pixel, not precision */\n> +       unsigned int stride_;\n>  \n>         SharedMemObject<SwIspStats> sharedStats_;\n>         SwIspStats stats_;\n> +       Benchmark bench_;\n>  };\n>  \n>  } /* namespace libcamera */\n> -- \n> 2.46.2\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 E9AB9C32DE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  9 Oct 2024 23:15:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 272E863527;\n\tThu, 10 Oct 2024 01:15:20 +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 9218E618C5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 01:15:18 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E41B99CA;\n\tThu, 10 Oct 2024 01:13:40 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"FJySB1vD\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1728515621;\n\tbh=oRyFIMGNQLmD5No7DeJXuF2ux824lVVAJcLuGz8a5aE=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=FJySB1vDYG6AU1fvNjT2Hxz9MmDEY55PWL3Su/4lRKmIvG5eed8WKR0HzQPWZcxxC\n\tspl4SF5gueqjkKSjQ7rFQab3q9xjPG3XfAJii4mGF8+GX14awHSYyXkqMK+aMdTxkI\n\t4lz4x++WG1CYLly9dSN+XxQbHpCjpUQ25QVLZR4M=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20241009200110.275544-5-hdegoede@redhat.com>","References":"<20241009200110.275544-1-hdegoede@redhat.com>\n\t<20241009200110.275544-5-hdegoede@redhat.com>","Subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Milan Zamazal <mzamazal@redhat.com>, Maxime Ripard <mripard@redhat.com>, \n\tHans de Goede <hdegoede@redhat.com>","To":"Hans de Goede <hdegoede@redhat.com>, libcamera-devel@lists.libcamera.org","Date":"Thu, 10 Oct 2024 00:15:15 +0100","Message-ID":"<172851571567.532453.8003880686390298604@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":31699,"web_url":"https://patchwork.libcamera.org/comment/31699/","msgid":"<df410fde-bd85-4262-b1dd-89f1d6c73e5c@redhat.com>","date":"2024-10-10T12:21:39","subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","submitter":{"id":102,"url":"https://patchwork.libcamera.org/api/people/102/","name":"Hans de Goede","email":"hdegoede@redhat.com"},"content":"Hi,\n\nOn 10-Oct-24 1:15 AM, Kieran Bingham wrote:\n> Quoting Hans de Goede (2024-10-09 21:01:10)\n>> Add a method to the SwstatsCpu class to process a whole Framebuffer in\n>> one go, rather then line by line. This is useful for gathering stats\n>> when debayering is not necessary or is not done on the CPU.\n> \n> I can't see how this is used yet. Is it just something that you would be\n> able to directly set up and call on a frame explicitly if desired?\n\nYes that is the idea. It could be e.g. used to do a raw-bayer pipeline\nwhile still having 3A in place.\n\n> I expect that's possible as it's RFC ... So I think I'll leave this one\n> to other soft-isp devs... But I can understand that it could be useful\n> for future development.\n\nRegards,\n\nHans\n\n\n\n\n>> ---\n>>  src/libcamera/software_isp/swstats_cpu.cpp | 72 ++++++++++++++++++++++\n>>  src/libcamera/software_isp/swstats_cpu.h   | 10 +++\n>>  2 files changed, 82 insertions(+)\n>>\n>> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n>> index 5e4246a9..117147c2 100644\n>> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n>> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n>> @@ -16,6 +16,7 @@\n>>  #include <libcamera/stream.h>\n>>  \n>>  #include \"libcamera/internal/bayer_format.h\"\n>> +#include \"libcamera/internal/mapped_framebuffer.h\"\n>>  \n>>  namespace libcamera {\n>>  \n>> @@ -363,8 +364,11 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>>         BayerFormat bayerFormat =\n>>                 BayerFormat::fromPixelFormat(inputCfg.pixelFormat);\n>>  \n>> +       stride_ = inputCfg.stride;\n>> +\n>>         if (bayerFormat.packing == BayerFormat::Packing::None &&\n>>             setupStandardBayerOrder(bayerFormat.order) == 0) {\n>> +               bpp_ = (bayerFormat.bitDepth + 7) & ~7;\n>>                 switch (bayerFormat.bitDepth) {\n>>                 case 8:\n>>                         stats0_ = &SwStatsCpu::statsBGGR8Line0;\n>> @@ -385,6 +389,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>>                 /* Skip every 3th and 4th line, sample every other 2x2 block */\n>>                 ySkipMask_ = 0x02;\n>>                 xShift_ = 0;\n>> +               bpp_ = 10;\n>>  \n>>                 switch (bayerFormat.order) {\n>>                 case BayerFormat::BGGR:\n>> @@ -425,4 +430,71 @@ void SwStatsCpu::setWindow(const Rectangle &window)\n>>         window_.height &= ~(patternSize_.height - 1);\n>>  }\n>>  \n>> +void SwStatsCpu::processFrame2(const uint8_t *src)\n>> +{\n>> +       unsigned int yEnd = window_.y + window_.height;\n>> +       const uint8_t *linePointers[3];\n>> +\n>> +       /* Adjust src to top left corner of the window */\n>> +       src += window_.y * stride_ + window_.x * bpp_ / 8;\n>> +\n>> +       for (unsigned int y = window_.y; y < yEnd; y += 2) {\n>> +               if (y & ySkipMask_) {\n>> +                       src += stride_ * 2;\n>> +                       continue;\n>> +               }\n>> +\n>> +               /* linePointers[0] is not used by any stats0_ functions */\n>> +               linePointers[1] = src;\n>> +               linePointers[2] = src + stride_;\n>> +               (this->*stats0_)(linePointers);\n>> +               src += stride_ * 2;\n>> +       }\n>> +}\n>> +\n>> +void SwStatsCpu::processFrame4(const uint8_t *src)\n>> +{\n>> +       const unsigned int yEnd = window_.y + window_.height;\n>> +       const uint8_t *linePointers[4];\n>> +\n>> +       /* Adjust src to top left corner of the window */\n>> +       src += window_.y * stride_ + window_.x * bpp_ / 8;\n>> +\n>> +       for (unsigned int y = window_.y; y < yEnd; y += 4) {\n>> +               if (y & ySkipMask_) {\n>> +                       src += stride_ * 4;\n>> +                       continue;\n>> +               }\n>> +\n>> +               /* linePointers[0] and [1] are not used by 4 line pattern stats0_ functions */\n>> +               linePointers[2] = src;\n>> +               linePointers[3] = src + stride_;\n>> +               (this->*stats0_)(linePointers);\n>> +               src += stride_ * 2;\n>> +\n>> +               linePointers[2] = src;\n>> +               linePointers[3] = src + stride_;\n>> +               (this->*stats2_)(linePointers);\n>> +               src += stride_ * 2;\n>> +       }\n>> +}\n>> +\n>> +void SwStatsCpu::processFrame(FrameBuffer *input)\n>> +{\n>> +       bench_.startFrame();\n>> +\n>> +       MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n>> +       if (!in.isValid()) {\n>> +               LOG(SwStatsCpu, Error) << \"mmap-ing buffer(s) failed\";\n>> +               return;\n>> +       }\n>> +\n>> +       if (patternSize_.height == 2)\n>> +               processFrame2(in.planes()[0].data());\n>> +       else\n>> +               processFrame4(in.planes()[0].data());\n>> +\n>> +       bench_.finishFrame();\n>> +}\n>> +\n>>  } /* namespace libcamera */\n>> diff --git a/src/libcamera/software_isp/swstats_cpu.h b/src/libcamera/software_isp/swstats_cpu.h\n>> index 26a2f462..bb178a04 100644\n>> --- a/src/libcamera/software_isp/swstats_cpu.h\n>> +++ b/src/libcamera/software_isp/swstats_cpu.h\n>> @@ -18,9 +18,12 @@\n>>  #include <libcamera/geometry.h>\n>>  \n>>  #include \"libcamera/internal/bayer_format.h\"\n>> +#include \"libcamera/internal/framebuffer.h\"\n>>  #include \"libcamera/internal/shared_mem_object.h\"\n>>  #include \"libcamera/internal/software_isp/swisp_stats.h\"\n>>  \n>> +#include \"benchmark.h\"\n>> +\n>>  namespace libcamera {\n>>  \n>>  class PixelFormat;\n>> @@ -42,6 +45,7 @@ public:\n>>         void setWindow(const Rectangle &window);\n>>         void startFrame();\n>>         void finishFrame(uint32_t frame, uint32_t bufferId);\n>> +       void processFrame(FrameBuffer *input);\n>>  \n>>         void processLine0(unsigned int y, const uint8_t *src[])\n>>         {\n>> @@ -77,6 +81,9 @@ private:\n>>         void statsBGGR10PLine0(const uint8_t *src[]);\n>>         void statsGBRG10PLine0(const uint8_t *src[]);\n>>  \n>> +       void processFrame2(const uint8_t *src);\n>> +       void processFrame4(const uint8_t *src);\n>> +\n>>         /* Variables set by configure(), used every line */\n>>         statsProcessFn stats0_;\n>>         statsProcessFn stats2_;\n>> @@ -89,9 +96,12 @@ private:\n>>         Size patternSize_;\n>>  \n>>         unsigned int xShift_;\n>> +       unsigned int bpp_; /* Memory used per pixel, not precision */\n>> +       unsigned int stride_;\n>>  \n>>         SharedMemObject<SwIspStats> sharedStats_;\n>>         SwIspStats stats_;\n>> +       Benchmark bench_;\n>>  };\n>>  \n>>  } /* namespace libcamera */\n>> -- \n>> 2.46.2\n>>\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 E4002C32E0\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 10 Oct 2024 12:21:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B66DE6536B;\n\tThu, 10 Oct 2024 14:21:46 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EAEBF6353A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 14:21:44 +0200 (CEST)","from mail-lf1-f71.google.com (mail-lf1-f71.google.com\n\t[209.85.167.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-42-WlpdkjxdN6iJXH20sYy2LA-1; Thu, 10 Oct 2024 08:21:42 -0400","by mail-lf1-f71.google.com with SMTP id\n\t2adb3069b0e04-5390f02e11bso863455e87.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 05:21:42 -0700 (PDT)","from ?IPV6:2001:1c00:c32:7800:5bfa:a036:83f0:f9ec?\n\t(2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl.\n\t[2001:1c00:c32:7800:5bfa:a036:83f0:f9ec])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-a99a80ef988sm82102466b.191.2024.10.10.05.21.39\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tThu, 10 Oct 2024 05:21:39 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"fVBqnS4S\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1728562903;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=lSDq2rTd0wxC9UQKGzpboMHWr2CpIWhR+FsOon8fEFo=;\n\tb=fVBqnS4ShckSCVcGJb3wLlV5d0wiiedXR+c7WRJA/1JwzPqixmgWpBDmKxldJJWmBfPQzi\n\trhJxnlwGbTOOBphpkHTHx9qO2J2Wf2NgKHqTNUppB6kzjmB2u9Q1gxy/w4HmZ/UJ3R0Om9\n\tcUqYMYnA2bySWYGk3qSTZhBZe5Ssxz8=","X-MC-Unique":"WlpdkjxdN6iJXH20sYy2LA-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1728562901; x=1729167701;\n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:cc:to:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=lSDq2rTd0wxC9UQKGzpboMHWr2CpIWhR+FsOon8fEFo=;\n\tb=nAkpchfVmJU0ZaEZ9LB7Uxuzmb1h5V7mT0g+1bWmfxNPoluS3UrTnfBVn44oeZqThg\n\tdvg5w2SPYEEXnq2jnKXl+MeLf1QsIZ1OMHZru2iZh9KOUzOXJ5/J2jTNtJeHJKclpDfX\n\taIYjIRlaRqE59Paw9V+oVIey/Nd3V3gmO7Pgi3wvaI8KgI7+I1I4R/vFYGsnKZ9fzR00\n\t/MvYyvtmQGtLuhAYpOOG3Ds6oLijZhY7gdGvqEayfqcW+Nr+9M1J99ZEBSDiJHR7kbg2\n\tlUWjc3smXqAL6yENw2+3pcxe6RjJQeKMRE55DC7RprqdoOzrtBCAjZQ+UHX8AlmROgnr\n\tjwkQ==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCWUt0dCvbgaDi3bOTHphd2bdegzYFFvxBfIOXP9sEWzf3J4fo3VyingKI/tj5Kq2gcc082QqpKB35pZ+Xz0PNY=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yx+iuJDnVAZQfHPdKhqPdJpwVm+UfTLIUXLzjYGYJAnNY4c+Tuu\n\tiM7kdf620w+KEz4WgzhA66pE3eUQPnOB9pz07f6+woshyJPjWHSamcKLEYFUMHKOLPvCiybQMri\n\tkuYjpzPz/MSgMxPfQs7tgyzkcXE3cTWTHJhJuXoWiFRcKifsDos961fxfk+KkpNdmiONAPZs=","X-Received":["by 2002:a05:6512:b29:b0:539:a353:279c with SMTP id\n\t2adb3069b0e04-539c48ea8dcmr3644419e87.28.1728562900803; \n\tThu, 10 Oct 2024 05:21:40 -0700 (PDT)","by 2002:a05:6512:b29:b0:539:a353:279c with SMTP id\n\t2adb3069b0e04-539c48ea8dcmr3644392e87.28.1728562900287; \n\tThu, 10 Oct 2024 05:21:40 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IHYqnTj8UCA+obATSuPAj9B1SlieM6wZ4pgs89e1QRMb0G+2o+U7V76Jz5vhQiB2SzxifpnyQ==","Message-ID":"<df410fde-bd85-4262-b1dd-89f1d6c73e5c@redhat.com>","Date":"Thu, 10 Oct 2024 14:21:39 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Cc":"Milan Zamazal <mzamazal@redhat.com>, Maxime Ripard <mripard@redhat.com>","References":"<20241009200110.275544-1-hdegoede@redhat.com>\n\t<20241009200110.275544-5-hdegoede@redhat.com>\n\t<172851571567.532453.8003880686390298604@ping.linuxembedded.co.uk>","From":"Hans de Goede <hdegoede@redhat.com>","In-Reply-To":"<172851571567.532453.8003880686390298604@ping.linuxembedded.co.uk>","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US, nl","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"7bit","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":31772,"web_url":"https://patchwork.libcamera.org/comment/31772/","msgid":"<878quogk21.fsf@redhat.com>","date":"2024-10-16T15:10:46","subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hans de Goede <hdegoede@redhat.com> writes:\n\n> Add a method to the SwstatsCpu class to process a whole Framebuffer in\n> one go, rather then line by line. This is useful for gathering stats\n> when debayering is not necessary or is not done on the CPU.\n\nMakes sense.  Although the actual use may be trickier, let's see.\n\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\n\n> Signed-off-by: Hans de Goede <hdegoede@redhat.com>\n>\n> ---\n>  src/libcamera/software_isp/swstats_cpu.cpp | 72 ++++++++++++++++++++++\n>  src/libcamera/software_isp/swstats_cpu.h   | 10 +++\n>  2 files changed, 82 insertions(+)\n>\n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index 5e4246a9..117147c2 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -16,6 +16,7 @@\n>  #include <libcamera/stream.h>\n>  \n>  #include \"libcamera/internal/bayer_format.h\"\n> +#include \"libcamera/internal/mapped_framebuffer.h\"\n>  \n>  namespace libcamera {\n>  \n> @@ -363,8 +364,11 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputCfg.pixelFormat);\n>  \n> +\tstride_ = inputCfg.stride;\n> +\n>  \tif (bayerFormat.packing == BayerFormat::Packing::None &&\n>  \t    setupStandardBayerOrder(bayerFormat.order) == 0) {\n> +\t\tbpp_ = (bayerFormat.bitDepth + 7) & ~7;\n>  \t\tswitch (bayerFormat.bitDepth) {\n>  \t\tcase 8:\n>  \t\t\tstats0_ = &SwStatsCpu::statsBGGR8Line0;\n> @@ -385,6 +389,7 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n>  \t\t/* Skip every 3th and 4th line, sample every other 2x2 block */\n>  \t\tySkipMask_ = 0x02;\n>  \t\txShift_ = 0;\n> +\t\tbpp_ = 10;\n>  \n>  \t\tswitch (bayerFormat.order) {\n>  \t\tcase BayerFormat::BGGR:\n> @@ -425,4 +430,71 @@ void SwStatsCpu::setWindow(const Rectangle &window)\n>  \twindow_.height &= ~(patternSize_.height - 1);\n>  }\n>  \n> +void SwStatsCpu::processFrame2(const uint8_t *src)\n> +{\n> +\tunsigned int yEnd = window_.y + window_.height;\n> +\tconst uint8_t *linePointers[3];\n> +\n> +\t/* Adjust src to top left corner of the window */\n> +\tsrc += window_.y * stride_ + window_.x * bpp_ / 8;\n> +\n> +\tfor (unsigned int y = window_.y; y < yEnd; y += 2) {\n> +\t\tif (y & ySkipMask_) {\n> +\t\t\tsrc += stride_ * 2;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\t/* linePointers[0] is not used by any stats0_ functions */\n> +\t\tlinePointers[1] = src;\n> +\t\tlinePointers[2] = src + stride_;\n> +\t\t(this->*stats0_)(linePointers);\n> +\t\tsrc += stride_ * 2;\n> +\t}\n> +}\n> +\n> +void SwStatsCpu::processFrame4(const uint8_t *src)\n> +{\n> +\tconst unsigned int yEnd = window_.y + window_.height;\n> +\tconst uint8_t *linePointers[4];\n> +\n> +\t/* Adjust src to top left corner of the window */\n> +\tsrc += window_.y * stride_ + window_.x * bpp_ / 8;\n> +\n> +\tfor (unsigned int y = window_.y; y < yEnd; y += 4) {\n> +\t\tif (y & ySkipMask_) {\n> +\t\t\tsrc += stride_ * 4;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\t/* linePointers[0] and [1] are not used by 4 line pattern stats0_ functions */\n> +\t\tlinePointers[2] = src;\n> +\t\tlinePointers[3] = src + stride_;\n> +\t\t(this->*stats0_)(linePointers);\n> +\t\tsrc += stride_ * 2;\n> +\n> +\t\tlinePointers[2] = src;\n> +\t\tlinePointers[3] = src + stride_;\n> +\t\t(this->*stats2_)(linePointers);\n> +\t\tsrc += stride_ * 2;\n> +\t}\n> +}\n> +\n> +void SwStatsCpu::processFrame(FrameBuffer *input)\n> +{\n> +\tbench_.startFrame();\n> +\n> +\tMappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);\n> +\tif (!in.isValid()) {\n> +\t\tLOG(SwStatsCpu, Error) << \"mmap-ing buffer(s) failed\";\n> +\t\treturn;\n> +\t}\n> +\n> +\tif (patternSize_.height == 2)\n> +\t\tprocessFrame2(in.planes()[0].data());\n> +\telse\n> +\t\tprocessFrame4(in.planes()[0].data());\n> +\n> +\tbench_.finishFrame();\n> +}\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/software_isp/swstats_cpu.h b/src/libcamera/software_isp/swstats_cpu.h\n> index 26a2f462..bb178a04 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.h\n> +++ b/src/libcamera/software_isp/swstats_cpu.h\n> @@ -18,9 +18,12 @@\n>  #include <libcamera/geometry.h>\n>  \n>  #include \"libcamera/internal/bayer_format.h\"\n> +#include \"libcamera/internal/framebuffer.h\"\n>  #include \"libcamera/internal/shared_mem_object.h\"\n>  #include \"libcamera/internal/software_isp/swisp_stats.h\"\n>  \n> +#include \"benchmark.h\"\n> +\n>  namespace libcamera {\n>  \n>  class PixelFormat;\n> @@ -42,6 +45,7 @@ public:\n>  \tvoid setWindow(const Rectangle &window);\n>  \tvoid startFrame();\n>  \tvoid finishFrame(uint32_t frame, uint32_t bufferId);\n> +\tvoid processFrame(FrameBuffer *input);\n>  \n>  \tvoid processLine0(unsigned int y, const uint8_t *src[])\n>  \t{\n> @@ -77,6 +81,9 @@ private:\n>  \tvoid statsBGGR10PLine0(const uint8_t *src[]);\n>  \tvoid statsGBRG10PLine0(const uint8_t *src[]);\n>  \n> +\tvoid processFrame2(const uint8_t *src);\n> +\tvoid processFrame4(const uint8_t *src);\n> +\n>  \t/* Variables set by configure(), used every line */\n>  \tstatsProcessFn stats0_;\n>  \tstatsProcessFn stats2_;\n> @@ -89,9 +96,12 @@ private:\n>  \tSize patternSize_;\n>  \n>  \tunsigned int xShift_;\n> +\tunsigned int bpp_; /* Memory used per pixel, not precision */\n> +\tunsigned int stride_;\n>  \n>  \tSharedMemObject<SwIspStats> sharedStats_;\n>  \tSwIspStats stats_;\n> +\tBenchmark bench_;\n>  };\n>  \n>  } /* namespace libcamera */","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 C1E89C32FA\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 16 Oct 2024 15:10:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C9B9965383;\n\tWed, 16 Oct 2024 17:10:54 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 92A136537E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 16 Oct 2024 17:10:52 +0200 (CEST)","from mail-wm1-f71.google.com (mail-wm1-f71.google.com\n\t[209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-671-fiI0-XTrOauczOZmx36jNw-1; Wed, 16 Oct 2024 11:10:50 -0400","by mail-wm1-f71.google.com with SMTP id\n\t5b1f17b1804b1-43057c9b32bso43621555e9.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 16 Oct 2024 08:10:49 -0700 (PDT)","from nuthatch (ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-4313fe99a40sm52213075e9.48.2024.10.16.08.10.47\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 16 Oct 2024 08:10:47 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"hnHv5VfE\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1729091451;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=Pkh889KQjxODdkUpxpcAlv7+O0tfjud25vDYeXkdJks=;\n\tb=hnHv5VfEu1tge7WNpRJr7SDVqaKfkG/LnvJkJ1oOP24ix3umuI5J5tuhFnCz8jqezyoo/T\n\t/3Ygry8UbVBL9iBDXphLw8YyplzCVnhosaBQBha6J838cyiOIg/CJVdBvkOY+7Sen4kQtw\n\tvevd0FkD3lRPbFQ6ZNtWOihPiMVZWIE=","X-MC-Unique":"fiI0-XTrOauczOZmx36jNw-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1729091449; x=1729696249;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=Pkh889KQjxODdkUpxpcAlv7+O0tfjud25vDYeXkdJks=;\n\tb=nIJ5O/xaaSdoWfwJzvjksik2JJxDoeU1oxNmciMCgziyGFVnufefd4z//3wVD0fyF8\n\tpvRXUrqn5HZwfHxKjnXBIefFR9XFNbRb+LzA7j46Vch98s0F5sP8Lx2Ta3iZOHvmJfJL\n\tL4EHSwcdLw+QCIPUNxFzJqSBiPRBt/yzLc3OqQHCHOB9R5J82V+s2KXtuUvajLAsfqWv\n\tsU1Dvd8awQP8aiR53yLfNPA6idka3P836xn+oWkbAs0Tz+55mpM4lhqAVL/KGcklz6bJ\n\t++knopaCpdyZTFIl/K2g/vcz8Gk0fFEjaxZmabaDGYy4q/Xf4j2oFTt7e/2WIhf/U0hO\n\tZN3w==","X-Gm-Message-State":"AOJu0YxHdWeChA75iymEYkHpSUYRrcb14l8uRipfEp/mRKZFVGZ/aMSu\n\tQYdaYLhEQXcM4QK/4t2tV+0R6Q6qz1FZRkzk3EHcnOWUixr4nh3jBAR3NsyDzKvf4xQ8Mp94W2F\n\tJr9fKOKppX9QKEVX6jJqb1nwwVKA3UK4C7mVXC+KWb2AWkByKp48H69x+Hn6DyNl7K2rQ7qg=","X-Received":["by 2002:a05:600c:4f83:b0:431:1d97:2b0a with SMTP id\n\t5b1f17b1804b1-4314a31acfdmr36632455e9.15.1729091448732; \n\tWed, 16 Oct 2024 08:10:48 -0700 (PDT)","by 2002:a05:600c:4f83:b0:431:1d97:2b0a with SMTP id\n\t5b1f17b1804b1-4314a31acfdmr36632275e9.15.1729091448339; \n\tWed, 16 Oct 2024 08:10:48 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IF2tCUwSt5Y/EPjDbMBOapL1ZBoPkhgdgYIOJSb0mo+mW8xAAsyyg+DDkB2o9f9GzZ2UPk0iQ==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Hans de Goede <hdegoede@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org, Maxime Ripard <mripard@redhat.com>","Subject":"Re: [RFC 4/4] libcamera: swstats_cpu: Add processFrame() method","In-Reply-To":"<20241009200110.275544-5-hdegoede@redhat.com> (Hans de Goede's\n\tmessage of \"Wed, 9 Oct 2024 22:01:10 +0200\")","References":"<20241009200110.275544-1-hdegoede@redhat.com>\n\t<20241009200110.275544-5-hdegoede@redhat.com>","Date":"Wed, 16 Oct 2024 17:10:46 +0200","Message-ID":"<878quogk21.fsf@redhat.com>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]