[{"id":19011,"web_url":"https://patchwork.libcamera.org/comment/19011/","msgid":"<YSQZkw9Tk17SA3GU@pendragon.ideasonboard.com>","date":"2021-08-23T21:56:35","subject":"Re: [libcamera-devel] [RFC PATCH 3/3] android: camera_buffer: Add\n\tstride/offset/size function","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Hiro,\n\nThank you for the patch.\n\nOn Mon, Aug 23, 2021 at 09:43:21PM +0900, Hirokazu Honda wrote:\n> This adds getter functions of stride, offset and size to CameraBuffer\n> interface.\n> \n> Signed-off-by: Hirokazu Honda <hiroh@chromium.org>\n> ---\n>  src/android/camera_buffer.h              | 16 +++++\n>  src/android/mm/cros_camera_buffer.cpp    | 19 ++++++\n>  src/android/mm/generic_camera_buffer.cpp | 78 ++++++++++++++++++------\n>  3 files changed, 94 insertions(+), 19 deletions(-)\n> \n> diff --git a/src/android/camera_buffer.h b/src/android/camera_buffer.h\n> index 87df2570..226a8f5c 100644\n> --- a/src/android/camera_buffer.h\n> +++ b/src/android/camera_buffer.h\n> @@ -31,6 +31,10 @@ public:\n>  \tlibcamera::Span<const uint8_t> plane(unsigned int plane) const;\n>  \tlibcamera::Span<uint8_t> plane(unsigned int plane);\n>  \n> +\tunsigned int stride(unsigned int plane) const;\n> +\tunsigned int offset(unsigned int plane) const;\n> +\tunsigned int size(unsigned int plane) const;\n> +\n>  \tsize_t jpegBufferSize(size_t maxJpegBufferSize) const;\n>  };\n>  \n> @@ -62,6 +66,18 @@ Span<uint8_t> CameraBuffer::plane(unsigned int plane)\t\t\t\\\n>  {\t\t\t\t\t\t\t\t\t\\\n>  \treturn _d()->plane(plane);\t\t\t\t\t\\\n>  }\t\t\t\t\t\t\t\t\t\\\n> +unsigned int CameraBuffer::stride(unsigned int plane) const\t\t\\\n> +{\t\t\t\t\t\t\t\t\t\\\n> +\treturn _d()->stride(plane);\t\t\t\t\t\\\n> +}\t\t\t\t\t\t\t\t\t\\\n> +unsigned int CameraBuffer::offset(unsigned int plane) const\t\t\\\n> +{\t\t\t\t\t\t\t\t\t\\\n> +\treturn _d()->offset(plane);\t\t\t\t\t\\\n> +}\t\t\t\t\t\t\t\t\t\\\n> +unsigned int CameraBuffer::size(unsigned int plane) const\t\t\\\n> +{\t\t\t\t\t\t\t\t\t\\\n> +\treturn _d()->size(plane);\t\t\t\t\t\\\n> +}\t\t\t\t\t\t\t\t\t\\\n>  size_t CameraBuffer::jpegBufferSize(size_t maxJpegBufferSize) const\t\\\n>  {\t\t\t\t\t\t\t\t\t\\\n>  \treturn _d()->jpegBufferSize(maxJpegBufferSize);\t\t\t\\\n> diff --git a/src/android/mm/cros_camera_buffer.cpp b/src/android/mm/cros_camera_buffer.cpp\n> index 85ef6480..4ba24f79 100644\n> --- a/src/android/mm/cros_camera_buffer.cpp\n> +++ b/src/android/mm/cros_camera_buffer.cpp\n> @@ -31,6 +31,10 @@ public:\n>  \n>  \tSpan<uint8_t> plane(unsigned int plane);\n>  \n> +\tunsigned int stride(unsigned int plane) const;\n> +\tunsigned int offset(unsigned int plane) const;\n> +\tunsigned int size(unsigned int plane) const;\n> +\n>  \tsize_t jpegBufferSize(size_t maxJpegBufferSize) const;\n>  \n>  private:\n> @@ -112,6 +116,21 @@ Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n>  \t\t bufferManager_->GetPlaneSize(handle_, plane) };\n>  }\n>  \n> +unsigned int CameraBuffer::Private::stride(unsigned int plane) const\n> +{\n> +\treturn cros::CameraBufferManager::GetPlaneStride(handle_, plane);\n> +}\n> +\n> +unsigned int CameraBuffer::Private::offset(unsigned int plane) const\n> +{\n> +\treturn cros::CameraBufferManager::GetPlaneOffset(handle_, plane);\n> +}\n> +\n> +unsigned int CameraBuffer::Private::size(unsigned int plane) const\n> +{\n> +\treturn cros::CameraBufferManager::GetPlaneSize(handle_, plane);\n> +}\n> +\n>  size_t CameraBuffer::Private::jpegBufferSize([[maybe_unused]] size_t maxJpegBufferSize) const\n>  {\n>  \treturn bufferManager_->GetPlaneSize(handle_, 0);\n> diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp\n> index 6c1e4611..b296b3e3 100644\n> --- a/src/android/mm/generic_camera_buffer.cpp\n> +++ b/src/android/mm/generic_camera_buffer.cpp\n> @@ -34,15 +34,24 @@ public:\n>  \n>  \tSpan<uint8_t> plane(unsigned int plane);\n>  \n> +\tunsigned int stride(unsigned int plane) const;\n> +\tunsigned int offset(unsigned int plane) const;\n> +\tunsigned int size(unsigned int plane) const;\n> +\n>  \tsize_t jpegBufferSize(size_t maxJpegBufferSize) const;\n>  \n>  private:\n> +\tstruct PlaneInfo {\n> +\t\tunsigned int stride;\n> +\t\tunsigned int offset;\n> +\t\tunsigned int size;\n> +\t};\n> +\n>  \tbool Map();\n>  \n>  \tint fd_;\n>  \tint flags_;\n> -\tlibcamera::Size size_;\n> -\tlibcamera::PixelFormatInfo info_;\n> +\tstd::vector<PlaneInfo> planeInfo_;\n>  \t/* \\todo remove planes_ is added to MappedBuffer. */\n>  \tstd::vector<Span<uint8_t>> planes_;\n>  };\n> @@ -51,7 +60,7 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n>  \t\t\t       buffer_handle_t camera3Buffer,\n>  \t\t\t       libcamera::PixelFormat pixelFormat,\n>  \t\t\t       const libcamera::Size &size, int flags)\n> -\t: fd_(-1), flags_(flags), size_(size)\n> +\t: fd_(-1), flags_(flags)\n>  {\n>  \terror_ = 0;\n>  \n> @@ -68,13 +77,29 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n>  \t\treturn;\n>  \t}\n>  \n> -\tinfo_ = libcamera::PixelFormatInfo::info(pixelFormat);\n> -\tif (!info_.isValid()) {\n> +\tconst auto &info = libcamera::PixelFormatInfo::info(pixelFormat);\n> +\tif (!info.isValid()) {\n>  \t\terror_ = EINVAL;\n>  \t\tLOG(HAL, Error) << \"Invalid pixel format: \"\n>  \t\t\t\t<< pixelFormat.toString();\n>  \t\treturn;\n>  \t}\n> +\n> +\tconst unsigned int numPlanes = info.numPlanes();\n> +\tplaneInfo_.resize(numPlanes);\n> +\tunsigned int offset = 0;\n> +\tfor (unsigned int i = 0; i < numPlanes; ++i) {\n> +\t\tconst unsigned int vertSubSample = info.planes[i].verticalSubSampling;\n> +\t\tconst unsigned int stride = info.stride(size.width, i, 1u);\n> +\t\tconst unsigned int planeSize =\n> +\t\t\tstride * ((size.height + vertSubSample - 1) / vertSubSample);\n> +\n> +\t\tplaneInfo_[i].stride = stride;\n> +\t\tplaneInfo_[i].offset = offset;\n> +\t\tplaneInfo_[i].size = planeSize;\n> +\n> +\t\toffset += planeSize;\n> +\t}\n\nAh, I see this code moving back to the constructor, as I mentioned in\nthe review of 2/3 :-) If it doesn't make the patches too ugly, it would\nbe nice to keep it in the constructor in 2/3 instead of moving it back.\n\n>  }\n>  \n>  CameraBuffer::Private::~Private()\n> @@ -83,7 +108,7 @@ CameraBuffer::Private::~Private()\n>  \n>  unsigned int CameraBuffer::Private::numPlanes() const\n>  {\n> -\treturn info_.numPlanes();\n> +\treturn planeInfo_.size();\n>  }\n>  \n>  Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n> @@ -97,6 +122,30 @@ Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n>  \treturn planes_[plane];\n>  }\n>  \n> +unsigned int CameraBuffer::Private::stride(unsigned int plane) const\n> +{\n> +\tif (plane >= planeInfo_.size())\n> +\t\treturn 0;\n> +\n> +\treturn planeInfo_[plane].stride;\n> +}\n> +\n> +unsigned int CameraBuffer::Private::offset(unsigned int plane) const\n> +{\n> +\tif (plane >= planeInfo_.size())\n> +\t\treturn 0;\n> +\n> +\treturn planeInfo_[plane].offset;\n> +}\n> +\n> +unsigned int CameraBuffer::Private::size(unsigned int plane) const\n> +{\n> +\tif (plane >= planeInfo_.size())\n> +\t\treturn 0;\n> +\n> +\treturn planeInfo_[plane].size;\n> +}\n> +\n>  size_t CameraBuffer::Private::jpegBufferSize(size_t maxJpegBufferSize) const\n>  {\n>  \tif (maps_.empty()) {\n> @@ -129,19 +178,10 @@ bool CameraBuffer::Private::Map()\n>  \t}\n>  \tmaps_.emplace_back(static_cast<uint8_t *>(address), bufferLength);\n>  \n> -\tconst unsigned int numPlanes = info_.numPlanes();\n> -\tplanes_.resize(numPlanes);\n> -\tunsigned int offset = 0;\n> -\tfor (unsigned int i = 0; i < numPlanes; ++i) {\n> -\t\tconst unsigned int vertSubSample = info_.planes[i].verticalSubSampling;\n> -\t\tconst unsigned int stride = info_.stride(size_.width, i, 1u);\n> -\t\tconst unsigned int planeSize =\n> -\t\t\tstride * ((size_.height + vertSubSample - 1) / vertSubSample);\n> -\n> -\t\tplanes_[i] = libcamera::Span<uint8_t>(\n> -\t\t\tstatic_cast<uint8_t *>(address) + offset, planeSize);\n> -\n> -\t\toffset += planeSize;\n> +\tplanes_.reserve(planeInfo_.size());\n> +\tfor (const auto &info : planeInfo_) {\n> +\t\tplanes_.emplace_back(\n> +\t\t\tstatic_cast<uint8_t *>(address) + info.offset, info.size);\n>  \t}\n>  \n>  \treturn true;","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 15650BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Aug 2021 21:56:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 43F45688A3;\n\tMon, 23 Aug 2021 23:56:47 +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 864B86025B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Aug 2021 23:56:45 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E82F92A5;\n\tMon, 23 Aug 2021 23:56:44 +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=\"DHIQ4HMg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1629755805;\n\tbh=7BSGaMQ5o8eQt+xLVNH59cHgMJxgKOuBqPRPtC4girM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=DHIQ4HMgiYtWc0ZmE/1vAvJIyrAcHOkNVpBf4ZIiq6ZrhNQ91KCAwzk5I+15B23WJ\n\tePd/NSB0E8nY4SEKFddyokmjQAQHvjtF9rC8M+FsvfBjxMI48HWCUa6Dr4WxVJjfBy\n\t7Q6Zxd9e3F05JyX2TD0HMU6dvIhPAJUQqcZrnhvU=","Date":"Tue, 24 Aug 2021 00:56:35 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Hirokazu Honda <hiroh@chromium.org>","Message-ID":"<YSQZkw9Tk17SA3GU@pendragon.ideasonboard.com>","References":"<20210823124321.980847-1-hiroh@chromium.org>\n\t<20210823124321.980847-4-hiroh@chromium.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210823124321.980847-4-hiroh@chromium.org>","Subject":"Re: [libcamera-devel] [RFC PATCH 3/3] android: camera_buffer: Add\n\tstride/offset/size function","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","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]