From patchwork Mon Jan 16 00:28:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18121 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 95C14C3294 for ; Mon, 16 Jan 2023 00:28:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5539F625F4; Mon, 16 Jan 2023 01:28:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828896; bh=23Lrt/FAquSj1ng9i9FMSOEJnmV9rWZH7Nf3CVIz3es=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=MaIyWhtLAKX0q5xL5YFeHyg0cuX8Q6COOnCenjO0c7iVNzMVmIu+5HJLNONFH1iFV MRNRpgLayRND5qHLeTnsyBTTuJD+mI8XcF10rVMz5/zEhVJL9VzcYYIbzqrZ/uvXJM yc7r4onIMA1ywC5dPBa8zP+eu2yt6a+JQ9D1Et2OIWvRoeaLRIVzazPbWB/RmWIv9U olsXo96bOIsB3G33RCfYE/IGM4SofStpVHhseljZChoMvKRzn2XUy1nCStL40VkXTk dVWjSRYp+M/wzG7jHgwNhvXK35VMpiUXxpw8dj4dp593TuFFqgcYgE2NP3F4xzUqfX Xxkqs1BU+rwXQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 635F1625ED for ; Mon, 16 Jan 2023 01:28:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tmClEgEw"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E1BD5997; Mon, 16 Jan 2023 01:28:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828894; bh=23Lrt/FAquSj1ng9i9FMSOEJnmV9rWZH7Nf3CVIz3es=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tmClEgEwJSdMaZM4Bp3J6SSitx4nxN5y8ySGAb8ZEqQoYTy4U9Dy7pUgVHU8nvp3f EWng7UQjFEtPrcBn8AAbYvKrxvRQWJl8JcI2Vs3N/0Y3n68acbr+YKhVAwZS83xwyq BBexMoQ1regKEg2tnZHvLsJvd8QJa5VisnXJ34nA= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:04 +0200 Message-Id: <20230116002808.16014-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.38.2 In-Reply-To: <20230116002808.16014-1-laurent.pinchart@ideasonboard.com> References: <20230116002808.16014-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 4/8] android: jpeg: Add an internal Encoder class in EncoderLibJpeg X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang To move the thumbnail encoder into EncoderLibJpeg in the following patch, this patch adds a wrapper/internal Encoder class that allows EncoderLibJpeg to have more than one encoder to tackle encoding of both captured images and their thumbnails. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- src/android/jpeg/encoder_libjpeg.cpp | 57 ++++++++++++++++++---------- src/android/jpeg/encoder_libjpeg.h | 30 +++++++++++---- 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index fd62bd9c7c5b..69fd91122aa6 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -68,7 +68,35 @@ const struct JPEGPixelFormatInfo &findPixelInfo(const PixelFormat &format) } /* namespace */ -EncoderLibJpeg::EncoderLibJpeg() +EncoderLibJpeg::EncoderLibJpeg() = default; +EncoderLibJpeg::~EncoderLibJpeg() = default; + +int EncoderLibJpeg::configure(const StreamConfiguration &cfg) +{ + return encoder_.configure(cfg); +} + +int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, + Span exifData, unsigned int quality) +{ + MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); + if (!frame.isValid()) { + LOG(JPEG, Error) << "Failed to map FrameBuffer: " + << strerror(frame.error()); + return frame.error(); + } + + return encoder_.encode(frame.planes(), dest, exifData, quality); +} + +int EncoderLibJpeg::encode(const std::vector> &src, + Span dest, Span exifData, + unsigned int quality) +{ + return encoder_.encode(src, dest, exifData, quality); +} + +EncoderLibJpeg::Encoder::Encoder() { /* \todo Expand error handling coverage with a custom handler. */ compress_.err = jpeg_std_error(&jerr_); @@ -76,12 +104,12 @@ EncoderLibJpeg::EncoderLibJpeg() jpeg_create_compress(&compress_); } -EncoderLibJpeg::~EncoderLibJpeg() +EncoderLibJpeg::Encoder::~Encoder() { jpeg_destroy_compress(&compress_); } -int EncoderLibJpeg::configure(const StreamConfiguration &cfg) +int EncoderLibJpeg::Encoder::configure(const StreamConfiguration &cfg) { const struct JPEGPixelFormatInfo info = findPixelInfo(cfg.pixelFormat); if (info.colorSpace == JCS_UNKNOWN) @@ -103,7 +131,7 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg) return 0; } -void EncoderLibJpeg::compressRGB(const std::vector> &planes) +void EncoderLibJpeg::Encoder::compressRGB(const std::vector> &planes) { unsigned char *src = const_cast(planes[0].data()); /* \todo Stride information should come from buffer configuration. */ @@ -121,7 +149,7 @@ void EncoderLibJpeg::compressRGB(const std::vector> &planes) * Compress the incoming buffer from a supported NV format. * This naively unpacks the semi-planar NV12 to a YUV888 format for libjpeg. */ -void EncoderLibJpeg::compressNV(const std::vector> &planes) +void EncoderLibJpeg::Encoder::compressNV(const std::vector> &planes) { uint8_t tmprowbuf[compress_.image_width * 3]; @@ -178,22 +206,9 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) } } -int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, - Span exifData, unsigned int quality) -{ - MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); - if (!frame.isValid()) { - LOG(JPEG, Error) << "Failed to map FrameBuffer : " - << strerror(frame.error()); - return frame.error(); - } - - return encode(frame.planes(), dest, exifData, quality); -} - -int EncoderLibJpeg::encode(const std::vector> &src, - Span dest, Span exifData, - unsigned int quality) +int EncoderLibJpeg::Encoder::encode(const std::vector> &src, + Span dest, Span exifData, + unsigned int quality) { unsigned char *destination = dest.data(); unsigned long size = dest.size(); diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 1b3ac067a1c0..eba591633cbb 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -32,14 +32,30 @@ public: unsigned int quality); private: - void compressRGB(const std::vector> &planes); - void compressNV(const std::vector> &planes); + class Encoder + { + public: + Encoder(); + ~Encoder(); - struct jpeg_compress_struct compress_; - struct jpeg_error_mgr jerr_; + int configure(const libcamera::StreamConfiguration &cfg); + int encode(const std::vector> &planes, + libcamera::Span destination, + libcamera::Span exifData, + unsigned int quality); - const libcamera::PixelFormatInfo *pixelFormatInfo_; + private: + void compressRGB(const std::vector> &planes); + void compressNV(const std::vector> &planes); - bool nv_; - bool nvSwap_; + struct jpeg_compress_struct compress_; + struct jpeg_error_mgr jerr_; + + const libcamera::PixelFormatInfo *pixelFormatInfo_; + + bool nv_; + bool nvSwap_; + }; + + Encoder encoder_; };