From patchwork Mon Jan 16 00:28:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18122 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 1A1E5BD87C for ; Mon, 16 Jan 2023 00:28:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D7063625ED; Mon, 16 Jan 2023 01:28:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828897; bh=hCooJpmA0EKWQFuR1X6So/CKwd7Gf4+on6DA8SWBGww=; 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=3gWaInUzVQ6rTkE0rc7KKiSC7IPKqlghCCsygxYQPtClotiG2kXLE0dxjbdt3OhXJ +SncFDsPTC8l7xf8UM0q8nRrY3J66jGq2LcDtp/Ihb6bF9JmqjvsbKIrCnMvaVfOaJ hiwe14JSyarmytwcoySwD4lSNxKlGB0lsJGjonwAfdVnW6Jj5oUFbxfsK/sIXkJ/Z2 736mUaOxddtOsvY3UC1T0fbIoG91wCzCzlDdctENJ/gonB7gdYf/NCDzHJTNWUvhhC sSe4+1pPsMLzkazm+Dl1BpscBI0vdlWpgRkTg2R5zW4tbhrXU3Htwgi3EAz3vhMXOF aLo1R7w4Ui1ww== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DB169625ED for ; Mon, 16 Jan 2023 01:28:15 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="wHC430gM"; 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 65DF5997; Mon, 16 Jan 2023 01:28:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828895; bh=hCooJpmA0EKWQFuR1X6So/CKwd7Gf4+on6DA8SWBGww=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wHC430gM0aIcgXtUxIge3rslF5zrbmdTnLpQ/4tjguoROrjQVqTXvcli4p2wIOE55 Tp0fWxsJ20bDjZOvOCz2M4AYq96ZthkDmPztQ8+3xKXNAT8DxOnlhPim9T4ji6Nn48 TtWurCL+f4r0tX+qC68ot1nFqYekkTgzIXfPJAmw= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:05 +0200 Message-Id: <20230116002808.16014-6-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 5/8] android: jpeg: Move generateThumbnail from PostProcessorJpeg to Encoder 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 In the following patch, generateThumbnail will have a different implementation in the jea encoder. Therefore, this patch moves the generateThumbnail function from PostProcessorJpeg to Encoder. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- src/android/jpeg/encoder.h | 4 ++ src/android/jpeg/encoder_libjpeg.cpp | 54 +++++++++++++++++++++--- src/android/jpeg/encoder_libjpeg.h | 15 ++++--- src/android/jpeg/post_processor_jpeg.cpp | 52 +---------------------- src/android/jpeg/post_processor_jpeg.h | 10 +---- 5 files changed, 65 insertions(+), 70 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index b974d367d8fa..5f9ef890023a 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -22,4 +22,8 @@ public: libcamera::Span destination, libcamera::Span exifData, unsigned int quality) = 0; + virtual void generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) = 0; }; diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index 69fd91122aa6..9bbf1abbe09c 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -73,7 +73,7 @@ EncoderLibJpeg::~EncoderLibJpeg() = default; int EncoderLibJpeg::configure(const StreamConfiguration &cfg) { - return encoder_.configure(cfg); + return captureEncoder_.configure(cfg); } int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, @@ -86,14 +86,56 @@ int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, return frame.error(); } - return encoder_.encode(frame.planes(), dest, exifData, quality); + return captureEncoder_.encode(frame.planes(), dest, exifData, quality); } -int EncoderLibJpeg::encode(const std::vector> &src, - Span dest, Span exifData, - unsigned int quality) +void EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) { - return encoder_.encode(src, dest, exifData, quality); + /* Stores the raw scaled-down thumbnail bytes. */ + std::vector rawThumbnail; + + thumbnailer_.createThumbnail(source, targetSize, &rawThumbnail); + + StreamConfiguration thCfg; + thCfg.size = targetSize; + thCfg.pixelFormat = thumbnailer_.pixelFormat(); + int ret = thumbnailEncoder_.configure(thCfg); + + if (!rawThumbnail.empty() && !ret) { + /* + * \todo Avoid value-initialization of all elements of the + * vector. + */ + thumbnail->resize(rawThumbnail.size()); + + /* + * Split planes manually as the encoder expects a vector of + * planes. + * + * \todo Pass a vector of planes directly to + * Thumbnailer::createThumbnailer above and remove the manual + * planes split from here. + */ + std::vector> thumbnailPlanes; + const PixelFormatInfo &formatNV12 = + PixelFormatInfo::info(formats::NV12); + size_t yPlaneSize = formatNV12.planeSize(targetSize, 0); + size_t uvPlaneSize = formatNV12.planeSize(targetSize, 1); + thumbnailPlanes.push_back({ rawThumbnail.data(), yPlaneSize }); + thumbnailPlanes.push_back({ rawThumbnail.data() + yPlaneSize, + uvPlaneSize }); + + int jpegSize = thumbnailEncoder_.encode(thumbnailPlanes, *thumbnail, + {}, quality); + thumbnail->resize(jpegSize); + + LOG(JPEG, Debug) + << "Thumbnail compress returned " + << jpegSize << " bytes"; + } } EncoderLibJpeg::Encoder::Encoder() diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index eba591633cbb..a022a72e02bf 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -15,6 +15,8 @@ #include +#include "thumbnailer.h" + class EncoderLibJpeg : public Encoder { public: @@ -26,10 +28,10 @@ public: libcamera::Span destination, libcamera::Span exifData, unsigned int quality) override; - int encode(const std::vector> &planes, - libcamera::Span destination, - libcamera::Span exifData, - unsigned int quality); + void generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) override; private: class Encoder @@ -57,5 +59,8 @@ private: bool nvSwap_; }; - Encoder encoder_; + Encoder captureEncoder_; + Encoder thumbnailEncoder_; + + Thumbnailer thumbnailer_; }; diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 0cf567164f99..69b18a2e5945 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -44,60 +44,11 @@ int PostProcessorJpeg::configure(const StreamConfiguration &inCfg, streamSize_ = outCfg.size; - thumbnailer_.configure(inCfg.size, inCfg.pixelFormat); - encoder_ = std::make_unique(); return encoder_->configure(inCfg); } -void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, - const Size &targetSize, - unsigned int quality, - std::vector *thumbnail) -{ - /* Stores the raw scaled-down thumbnail bytes. */ - std::vector rawThumbnail; - - thumbnailer_.createThumbnail(source, targetSize, &rawThumbnail); - - StreamConfiguration thCfg; - thCfg.size = targetSize; - thCfg.pixelFormat = thumbnailer_.pixelFormat(); - int ret = thumbnailEncoder_.configure(thCfg); - - if (!rawThumbnail.empty() && !ret) { - /* - * \todo Avoid value-initialization of all elements of the - * vector. - */ - thumbnail->resize(rawThumbnail.size()); - - /* - * Split planes manually as the encoder expects a vector of - * planes. - * - * \todo Pass a vector of planes directly to - * Thumbnailer::createThumbnailer above and remove the manual - * planes split from here. - */ - std::vector> thumbnailPlanes; - const PixelFormatInfo &formatNV12 = PixelFormatInfo::info(formats::NV12); - size_t yPlaneSize = formatNV12.planeSize(targetSize, 0); - size_t uvPlaneSize = formatNV12.planeSize(targetSize, 1); - thumbnailPlanes.push_back({ rawThumbnail.data(), yPlaneSize }); - thumbnailPlanes.push_back({ rawThumbnail.data() + yPlaneSize, uvPlaneSize }); - - int jpeg_size = thumbnailEncoder_.encode(thumbnailPlanes, - *thumbnail, {}, quality); - thumbnail->resize(jpeg_size); - - LOG(JPEG, Debug) - << "Thumbnail compress returned " - << jpeg_size << " bytes"; - } -} - void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBuffer) { ASSERT(encoder_); @@ -164,7 +115,8 @@ void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBu if (thumbnailSize != Size(0, 0)) { std::vector thumbnail; - generateThumbnail(source, thumbnailSize, quality, &thumbnail); + encoder_->generateThumbnail(source, thumbnailSize, + quality, &thumbnail); if (!thumbnail.empty()) exif.setThumbnail(std::move(thumbnail), Exif::Compression::JPEG); } diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index 98309b012a3b..f09c9a1d8738 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -8,12 +8,11 @@ #pragma once #include "../post_processor.h" -#include "encoder_libjpeg.h" -#include "thumbnailer.h" #include class CameraDevice; +class Encoder; class PostProcessorJpeg : public PostProcessor { @@ -25,14 +24,7 @@ public: void process(Camera3RequestDescriptor::StreamBuffer *streamBuffer) override; private: - void generateThumbnail(const libcamera::FrameBuffer &source, - const libcamera::Size &targetSize, - unsigned int quality, - std::vector *thumbnail); - CameraDevice *const cameraDevice_; std::unique_ptr encoder_; libcamera::Size streamSize_; - EncoderLibJpeg thumbnailEncoder_; - Thumbnailer thumbnailer_; };