[{"id":15371,"web_url":"https://patchwork.libcamera.org/comment/15371/","msgid":"<YD1+3DhXG9N25UFk@pendragon.ideasonboard.com>","date":"2021-03-01T23:55:08","subject":"Re: [libcamera-devel] [PATCH 07/10] android: post_processor: Use\n\tCameraBuffer API","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 patch.\n\nOn Mon, Mar 01, 2021 at 04:01:08PM +0100, Jacopo Mondi wrote:\n> Use the newly introduced CameraBuffer class as the type for the\n> destination buffer in the PostProcessor class hierarchy in place of the\n> libcamera::MappedFrameBuffer one and use its API to retrieve the length\n> and the location of the CameraBuffer plane allocated for JPEG\n> post-processing.\n> \n> Remove all the assumption on the underlying memory storage and only go\n> through the CameraBuffer API when dealing with memory buffers. To do so\n> rework the Encoder interface to use a raw pointer and an explicit size\n> to remove access to the Span<uint8_t> maps that serve as memory storage\n> for the current implementation but might not be ideal for other memory\n> backend.\n> \n> Now that the whole PostProcessor hierarchy has been converted to use\n> the CameraBuffer API remove libcamera::MappedBuffer as base class\n> of the CameraBuffer interface and only reply on its interface.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/android/camera_buffer.h              |  4 +---\n>  src/android/jpeg/post_processor_jpeg.cpp | 25 ++++++++----------------\n>  src/android/jpeg/post_processor_jpeg.h   |  2 +-\n>  src/android/mm/generic_camera_buffer.cpp |  1 +\n>  src/android/post_processor.h             |  4 +++-\n>  src/android/yuv/post_processor_yuv.cpp   | 20 +++++++++----------\n>  src/android/yuv/post_processor_yuv.h     |  6 ++++--\n>  7 files changed, 28 insertions(+), 34 deletions(-)\n> \n> diff --git a/src/android/camera_buffer.h b/src/android/camera_buffer.h\n> index ca4f4527c690..2311cdaf96b2 100644\n> --- a/src/android/camera_buffer.h\n> +++ b/src/android/camera_buffer.h\n> @@ -10,11 +10,9 @@\n>  #include <hardware/camera3.h>\n>  \n>  #include <libcamera/class.h>\n> -#include <libcamera/internal/buffer.h>\n>  #include <libcamera/span.h>\n>  \n> -class CameraBuffer final : public libcamera::Extensible,\n> -\t\t\t   public libcamera::MappedBuffer\n> +class CameraBuffer final : public libcamera::Extensible\n>  {\n>  \tLIBCAMERA_DECLARE_PRIVATE(CameraBuffer)\n>  \n> diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp\n> index ab5b63844067..83244ce6769e 100644\n> --- a/src/android/jpeg/post_processor_jpeg.cpp\n> +++ b/src/android/jpeg/post_processor_jpeg.cpp\n> @@ -83,13 +83,15 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source,\n>  }\n>  \n>  int PostProcessorJpeg::process(const FrameBuffer &source,\n> -\t\t\t       libcamera::MappedBuffer *destination,\n> +\t\t\t       CameraBuffer *destination,\n>  \t\t\t       const CameraMetadata &requestMetadata,\n>  \t\t\t       CameraMetadata *resultMetadata)\n>  {\n>  \tif (!encoder_)\n>  \t\treturn 0;\n>  \n> +\tASSERT(destination->numPlanes() == 1);\n> +\n>  \tcamera_metadata_ro_entry_t entry;\n>  \tint ret;\n>  \n> @@ -172,28 +174,17 @@ int PostProcessorJpeg::process(const FrameBuffer &source,\n>  \tconst uint8_t quality = ret ? *entry.data.u8 : 95;\n>  \tresultMetadata->addEntry(ANDROID_JPEG_QUALITY, &quality, 1);\n>  \n> -\tint jpeg_size = encoder_->encode(source, destination->maps()[0],\n> +\tint jpeg_size = encoder_->encode(source, destination->plane(0),\n>  \t\t\t\t\t exif.data(), quality);\n>  \tif (jpeg_size < 0) {\n>  \t\tLOG(JPEG, Error) << \"Failed to encode stream image\";\n>  \t\treturn jpeg_size;\n>  \t}\n>  \n> -\t/*\n> -\t * Fill in the JPEG blob header.\n> -\t *\n> -\t * The mapped size of the buffer is being returned as\n> -\t * substantially larger than the requested JPEG_MAX_SIZE\n> -\t * (which is referenced from maxJpegBufferSize_). Utilise\n> -\t * this static size to ensure the correct offset of the blob is\n> -\t * determined.\n> -\t *\n> -\t * \\todo Investigate if the buffer size mismatch is an issue or\n> -\t * expected behaviour.\n> -\t */\n> -\tuint8_t *resultPtr = destination->maps()[0].data() +\n> -\t\t\t     cameraDevice_->maxJpegBufferSize() -\n> -\t\t\t     sizeof(struct camera3_jpeg_blob);\n> +\t/* Fill in the JPEG blob header. */\n> +\tuint8_t *resultPtr = destination->plane(0).data()\n> +\t\t\t   + destination->plane(0).size()\n> +\t\t\t   - sizeof(struct camera3_jpeg_blob);\n>  \tauto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);\n>  \tblob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;\n>  \tblob->jpeg_size = jpeg_size;\n> diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h\n> index 7689de73c664..5d2d4ab224b1 100644\n> --- a/src/android/jpeg/post_processor_jpeg.h\n> +++ b/src/android/jpeg/post_processor_jpeg.h\n> @@ -25,7 +25,7 @@ public:\n>  \tint configure(const libcamera::StreamConfiguration &incfg,\n>  \t\t      const libcamera::StreamConfiguration &outcfg) override;\n>  \tint process(const libcamera::FrameBuffer &source,\n> -\t\t    libcamera::MappedBuffer *destination,\n> +\t\t    CameraBuffer *destination,\n>  \t\t    const CameraMetadata &requestMetadata,\n>  \t\t    CameraMetadata *resultMetadata) override;\n>  \n> diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp\n> index eedf16b76542..ea85be805260 100644\n> --- a/src/android/mm/generic_camera_buffer.cpp\n> +++ b/src/android/mm/generic_camera_buffer.cpp\n> @@ -7,6 +7,7 @@\n>  \n>  #include \"../camera_buffer.h\"\n>  \n> +#include <libcamera/internal/buffer.h>\n>  #include \"libcamera/internal/log.h\"\n>  \n>  using namespace libcamera;\n> diff --git a/src/android/post_processor.h b/src/android/post_processor.h\n> index ac40d3414892..4944078b490c 100644\n> --- a/src/android/post_processor.h\n> +++ b/src/android/post_processor.h\n> @@ -12,6 +12,8 @@\n>  \n>  #include <libcamera/internal/buffer.h>\n>  \n> +#include \"camera_buffer.h\"\n> +\n>  class CameraMetadata;\n>  \n>  class PostProcessor\n> @@ -22,7 +24,7 @@ public:\n>  \tvirtual int configure(const libcamera::StreamConfiguration &inCfg,\n>  \t\t\t      const libcamera::StreamConfiguration &outCfg) = 0;\n>  \tvirtual int process(const libcamera::FrameBuffer &source,\n> -\t\t\t    libcamera::MappedBuffer *destination,\n> +\t\t\t    CameraBuffer *destination,\n>  \t\t\t    const CameraMetadata &requestMetadata,\n>  \t\t\t    CameraMetadata *resultMetadata) = 0;\n>  };\n> diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp\n> index 1318349ad66b..b67364c8f147 100644\n> --- a/src/android/yuv/post_processor_yuv.cpp\n> +++ b/src/android/yuv/post_processor_yuv.cpp\n> @@ -48,7 +48,7 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg,\n>  }\n>  \n>  int PostProcessorYuv::process(const FrameBuffer &source,\n> -\t\t\t      libcamera::MappedBuffer *destination,\n> +\t\t\t      CameraBuffer *destination,\n>  \t\t\t      [[maybe_unused]] const CameraMetadata &requestMetadata,\n>  \t\t\t      [[maybe_unused]] CameraMetadata *metadata)\n>  {\n> @@ -66,9 +66,9 @@ int PostProcessorYuv::process(const FrameBuffer &source,\n>  \t\t\t\t    sourceMapped.maps()[1].data(),\n>  \t\t\t\t    sourceStride_[1],\n>  \t\t\t\t    sourceSize_.width, sourceSize_.height,\n> -\t\t\t\t    destination->maps()[0].data(),\n> +\t\t\t\t    destination->plane(0).data(),\n>  \t\t\t\t    destinationStride_[0],\n> -\t\t\t\t    destination->maps()[1].data(),\n> +\t\t\t\t    destination->plane(1).data(),\n>  \t\t\t\t    destinationStride_[1],\n>  \t\t\t\t    destinationSize_.width,\n>  \t\t\t\t    destinationSize_.height,\n> @@ -82,16 +82,16 @@ int PostProcessorYuv::process(const FrameBuffer &source,\n>  }\n>  \n>  bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source,\n> -\t\t\t\t      const libcamera::MappedBuffer &destination) const\n> +\t\t\t\t      const CameraBuffer &destination) const\n>  {\n>  \tif (source.planes().size() != 2) {\n>  \t\tLOG(YUV, Error) << \"Invalid number of source planes: \"\n>  \t\t\t\t<< source.planes().size();\n>  \t\treturn false;\n>  \t}\n> -\tif (destination.maps().size() != 2) {\n> +\tif (destination.numPlanes() != 2) {\n>  \t\tLOG(YUV, Error) << \"Invalid number of destination planes: \"\n> -\t\t\t\t<< destination.maps().size();\n> +\t\t\t\t<< destination.numPlanes();\n>  \t\treturn false;\n>  \t}\n>  \n> @@ -106,12 +106,12 @@ bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source,\n>  \t\t\t<< sourceLength_[1] << \"}\";\n>  \t\treturn false;\n>  \t}\n> -\tif (destination.maps()[0].size() < destinationLength_[0] ||\n> -\t    destination.maps()[1].size() < destinationLength_[1]) {\n> +\tif (destination.plane(0).size() < destinationLength_[0] ||\n> +\t    destination.plane(1).size() < destinationLength_[1]) {\n>  \t\tLOG(YUV, Error)\n>  \t\t\t<< \"The destination planes lengths are too small, actual size: {\"\n> -\t\t\t<< destination.maps()[0].size() << \", \"\n> -\t\t\t<< destination.maps()[1].size()\n> +\t\t\t<< destination.plane(0).size() << \", \"\n> +\t\t\t<< destination.plane(1).size()\n>  \t\t\t<< \"}, expected size: {\"\n>  \t\t\t<< sourceLength_[0] << \", \"\n>  \t\t\t<< sourceLength_[1] << \"}\";\n> diff --git a/src/android/yuv/post_processor_yuv.h b/src/android/yuv/post_processor_yuv.h\n> index c58b4cf790fc..94620dd0a870 100644\n> --- a/src/android/yuv/post_processor_yuv.h\n> +++ b/src/android/yuv/post_processor_yuv.h\n> @@ -9,6 +9,8 @@\n>  \n>  #include \"../post_processor.h\"\n>  \n> +#include \"../camera_buffer.h\"\n\nAs post_processor.h defines the process() function and thus pulls the\nCameraBuffer type definition, you don't need to include camera_buffer.h\nhere.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\n>  #include <libcamera/geometry.h>\n>  \n>  class CameraDevice;\n> @@ -21,13 +23,13 @@ public:\n>  \tint configure(const libcamera::StreamConfiguration &incfg,\n>  \t\t      const libcamera::StreamConfiguration &outcfg) override;\n>  \tint process(const libcamera::FrameBuffer &source,\n> -\t\t    libcamera::MappedBuffer *destination,\n> +\t\t    CameraBuffer *destination,\n>  \t\t    const CameraMetadata &requestMetadata,\n>  \t\t    CameraMetadata *metadata) override;\n>  \n>  private:\n>  \tbool isValidBuffers(const libcamera::FrameBuffer &source,\n> -\t\t\t    const libcamera::MappedBuffer &destination) const;\n> +\t\t\t    const CameraBuffer &destination) const;\n>  \tvoid calculateLengths(const libcamera::StreamConfiguration &inCfg,\n>  \t\t\t      const libcamera::StreamConfiguration &outCfg);\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 A6A83BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  1 Mar 2021 23:55:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 32AA668A8D;\n\tTue,  2 Mar 2021 00:55:39 +0100 (CET)","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 7CFEB602E9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  2 Mar 2021 00:55:37 +0100 (CET)","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 CC1AF45D;\n\tTue,  2 Mar 2021 00:55:36 +0100 (CET)"],"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=\"HBrcyy/1\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1614642937;\n\tbh=EMbYVnQVaVg3vp5pD4nJ9a1LfDkimPvkacOVnSHY3+c=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=HBrcyy/1yjNJngtbJ4aNpEUgljAHQYDMcBwkBA9Ad7ev3aNsi/vkbXuwLke5kiWAE\n\tNpxgUYcrR5Wad9w7flUnuYfSaVPcVvzDtIJpuDNc4uNfGUcdFfdna8DjLVsVJdplcu\n\tU1QkQkZOy94ZwboucOg2VWHpaZZuaqfOhXQ6NmnU=","Date":"Tue, 2 Mar 2021 01:55:08 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YD1+3DhXG9N25UFk@pendragon.ideasonboard.com>","References":"<20210301150111.61791-1-jacopo@jmondi.org>\n\t<20210301150111.61791-8-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210301150111.61791-8-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 07/10] android: post_processor: Use\n\tCameraBuffer API","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":"Han-lin Chen <hanlinchen@chromium.org>,\n\tlibcamera-devel@lists.libcamera.org, Daniel Hung-yu Wu <hywu@google.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>"}}]