From patchwork Mon Jan 16 00:28:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18118 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 D8E0FBD87C for ; Mon, 16 Jan 2023 00:28:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 92E0C625EA; Mon, 16 Jan 2023 01:28:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828892; bh=wmPq7P28jwxF2raIg3WaEvq4ng2ER7Eb+6lQp7HSeSI=; 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=SBt0p91Yyg88cdmQbUVQJS84DSdSm4fe3GD8tyWCsslpwQUUqr5iGu6ZVsgtSPgf9 AujKh0CsWwYarLcZNJlaxeGi8S8oqnxG7b0z9e8zPYwbsuqF4ghlrBwsLCMVziXIA2 FxsMaIeodqB03nREUoSPDsYTgSTOGLIhhMzpSo1WsoSzwobZzofHmsBDDEYCMsycS8 jXHXsutg0wfFfOg75YuAzRvJS41xsjnOCjNfmMxqtuIlmxcnTudEQUC0EuP7zn3bfO RFYKOSJGhdjdwGh9u/mDLc999o3MKCT4wn2VHfst1qWSzbMelWvYDYa45LhOtAJBlJ d4aq2YhDn1mUw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 79368625E7 for ; Mon, 16 Jan 2023 01:28:10 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mJq39e8S"; 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 C9FD3997; Mon, 16 Jan 2023 01:28:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828890; bh=wmPq7P28jwxF2raIg3WaEvq4ng2ER7Eb+6lQp7HSeSI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mJq39e8SCTFWIfnP3OZTtWGitCiJbHOHzn9mn0s/UsnV+pC0l5kCWnbnnZBOtITJD IT3vDjcAc2ns+xmkTPUb4YTHr9Wm18axgJfxeHegyzbYKYevfeDO7VTqYPZhT6b+Lc IjbnKnW1mxCg0pWpfmAMvD5gGjsoa41804j7a0r8= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:01 +0200 Message-Id: <20230116002808.16014-2-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 1/8] libcamera: framebuffer: Allow inheritance of FrameBuffer 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 add buffer_handle_t access in android, this patch allows inheritance of FrameBuffer to add a derived class in android. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Reviewed-by: Han-Lin Chen Signed-off-by: Laurent Pinchart --- include/libcamera/framebuffer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index 695539993f96..612448290a24 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -46,7 +46,7 @@ private: std::vector planes_; }; -class FrameBuffer final : public Extensible +class FrameBuffer : public Extensible { LIBCAMERA_DECLARE_PRIVATE() @@ -60,6 +60,7 @@ public: FrameBuffer(const std::vector &planes, unsigned int cookie = 0); FrameBuffer(std::unique_ptr d); + virtual ~FrameBuffer() {} const std::vector &planes() const; Request *request() const; From patchwork Mon Jan 16 00:28:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18119 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 F377DC3294 for ; Mon, 16 Jan 2023 00:28:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 52788625E8; Mon, 16 Jan 2023 01:28:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828893; bh=0dx1q0gSpebx1lZUR61mTZQQw6qIJ4BYIy3cdVECx60=; 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=qgADqPnLp2dY4vMMga2aZtJHl3jXn9LUziKP9fgGkLEKHZ9ZnwSSFn4SSUywqBNNC RNSuhPrQc5XlEfO8/0AXglSFJc9c3sSH4wYWFriQwag/eFgGyV+qmnLp/s/pwu/AWi l7EccIdFTudtoJeJPMz4QUe1K/Pi0w5xUQs0QJliRm27+skzEQDB/o1KHHSTa+kKHv +4inDjlRSe/LIJHAnaNnnzcVbNLRUE8Kea398yAQO4AOnmjm+mQZIaB2WN2Qj3Oq4f Ehr7o/XwQBvJwOUgHNZ/BbG+GKCLLfW0gHrE9r8dE7ZjEIZ/ACM2hhUVd0kq31FUjp otd5dkWj79pKw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A5203625E3 for ; Mon, 16 Jan 2023 01:28:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UTthdIrg"; 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 2F1CA9B4; Mon, 16 Jan 2023 01:28:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828891; bh=0dx1q0gSpebx1lZUR61mTZQQw6qIJ4BYIy3cdVECx60=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UTthdIrgRO0jcSXEr6zKazOmkBkZENZkkq4zPDgN0QKaA/zdt3f4wHLq9Os2x/FOJ JyLU68TQgckB2G/GDGZhKptRBva4v++0GZTSBl97BzRlCOLWo9dFsvbZaYqA/gzc94 FDnClmY9VQAMM02hQA6aklPAZtS+T1PMdfv+kgpc= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:02 +0200 Message-Id: <20230116002808.16014-3-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 2/8] android: framebuffer: Add HALFrameBuffer and replace FrameBuffer 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 HALFrameBuffer is derived from FrameBuffer with access to buffer_handle_t, which is needed for JEA usage. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Reviewed-by: Han-Lin Chen Signed-off-by: Laurent Pinchart --- src/android/camera_device.cpp | 5 ++-- src/android/camera_device.h | 3 ++- src/android/camera_request.h | 3 ++- src/android/frame_buffer_allocator.h | 7 ++--- src/android/hal_framebuffer.cpp | 22 ++++++++++++++++ src/android/hal_framebuffer.h | 26 +++++++++++++++++++ src/android/meson.build | 1 + .../mm/cros_frame_buffer_allocator.cpp | 9 ++++--- .../mm/generic_frame_buffer_allocator.cpp | 11 +++++--- 9 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 src/android/hal_framebuffer.cpp create mode 100644 src/android/hal_framebuffer.h diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index b20e389b9d30..1f7ce4402b63 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -30,6 +30,7 @@ #include "camera_hal_config.h" #include "camera_ops.h" #include "camera_request.h" +#include "hal_framebuffer.h" using namespace libcamera; @@ -771,7 +772,7 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) return 0; } -std::unique_ptr +std::unique_ptr CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer, PixelFormat pixelFormat, const Size &size) { @@ -794,7 +795,7 @@ CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer, planes[i].length = buf.size(i); } - return std::make_unique(planes); + return std::make_unique(planes, camera3buffer); } int CameraDevice::processControls(Camera3RequestDescriptor *descriptor) diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 64050416e67e..43ee01592e77 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -29,6 +29,7 @@ #include "camera_capabilities.h" #include "camera_metadata.h" #include "camera_stream.h" +#include "hal_framebuffer.h" #include "jpeg/encoder.h" class Camera3RequestDescriptor; @@ -83,7 +84,7 @@ private: void stop() LIBCAMERA_TSA_EXCLUDES(stateMutex_); - std::unique_ptr + std::unique_ptr createFrameBuffer(const buffer_handle_t camera3buffer, libcamera::PixelFormat pixelFormat, const libcamera::Size &size); diff --git a/src/android/camera_request.h b/src/android/camera_request.h index 37b6ae326f3e..20aba79d5057 100644 --- a/src/android/camera_request.h +++ b/src/android/camera_request.h @@ -21,6 +21,7 @@ #include #include "camera_metadata.h" +#include "hal_framebuffer.h" class CameraBuffer; class CameraStream; @@ -44,7 +45,7 @@ public: CameraStream *stream; buffer_handle_t *camera3Buffer; - std::unique_ptr frameBuffer; + std::unique_ptr frameBuffer; libcamera::UniqueFD fence; Status status = Status::Success; libcamera::FrameBuffer *internalBuffer = nullptr; diff --git a/src/android/frame_buffer_allocator.h b/src/android/frame_buffer_allocator.h index 5d2eeda17fc5..e5c9492279d3 100644 --- a/src/android/frame_buffer_allocator.h +++ b/src/android/frame_buffer_allocator.h @@ -13,9 +13,10 @@ #include #include -#include #include +#include "hal_framebuffer.h" + class CameraDevice; class PlatformFrameBufferAllocator : libcamera::Extensible @@ -31,7 +32,7 @@ public: * Note: The returned FrameBuffer needs to be destroyed before * PlatformFrameBufferAllocator is destroyed. */ - std::unique_ptr allocate( + std::unique_ptr allocate( int halPixelFormat, const libcamera::Size &size, uint32_t usage); }; @@ -44,7 +45,7 @@ PlatformFrameBufferAllocator::PlatformFrameBufferAllocator( \ PlatformFrameBufferAllocator::~PlatformFrameBufferAllocator() \ { \ } \ -std::unique_ptr \ +std::unique_ptr \ PlatformFrameBufferAllocator::allocate(int halPixelFormat, \ const libcamera::Size &size, \ uint32_t usage) \ diff --git a/src/android/hal_framebuffer.cpp b/src/android/hal_framebuffer.cpp new file mode 100644 index 000000000000..3f3d1ed1c327 --- /dev/null +++ b/src/android/hal_framebuffer.cpp @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * hal_framebuffer.cpp - HAL Frame Buffer Handling + */ + +#include "hal_framebuffer.h" + +#include + +HALFrameBuffer::HALFrameBuffer(std::unique_ptr d, + buffer_handle_t handle) + : FrameBuffer(std::move(d)), handle_(handle) +{ +} + +HALFrameBuffer::HALFrameBuffer(const std::vector &planes, + buffer_handle_t handle) + : FrameBuffer(planes), handle_(handle) +{ +} diff --git a/src/android/hal_framebuffer.h b/src/android/hal_framebuffer.h new file mode 100644 index 000000000000..dc96a7e193da --- /dev/null +++ b/src/android/hal_framebuffer.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * hal_framebuffer.h - HAL Frame Buffer Handling + */ + +#pragma once + +#include "libcamera/internal/framebuffer.h" + +#include + +class HALFrameBuffer final : public libcamera::FrameBuffer +{ +public: + HALFrameBuffer(std::unique_ptr d, + buffer_handle_t handle); + HALFrameBuffer(const std::vector &planes, + buffer_handle_t handle); + + buffer_handle_t handle() const { return handle_; } + +private: + buffer_handle_t handle_; +}; diff --git a/src/android/meson.build b/src/android/meson.build index 1bba54de07a8..b543c14371aa 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -46,6 +46,7 @@ android_hal_sources = files([ 'camera_ops.cpp', 'camera_request.cpp', 'camera_stream.cpp', + 'hal_framebuffer.cpp', 'jpeg/encoder_libjpeg.cpp', 'jpeg/exif.cpp', 'jpeg/post_processor_jpeg.cpp', diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp index 0665c77b1377..0a5c59f2a697 100644 --- a/src/android/mm/cros_frame_buffer_allocator.cpp +++ b/src/android/mm/cros_frame_buffer_allocator.cpp @@ -16,6 +16,7 @@ #include "../camera_device.h" #include "../frame_buffer_allocator.h" +#include "../hal_framebuffer.h" #include "cros-camera/camera_buffer_manager.h" using namespace libcamera; @@ -48,11 +49,11 @@ public: { } - std::unique_ptr + std::unique_ptr allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage); }; -std::unique_ptr +std::unique_ptr PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage) @@ -81,8 +82,8 @@ PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, plane.length = cros::CameraBufferManager::GetPlaneSize(handle, i); } - return std::make_unique( - std::make_unique(std::move(scopedHandle), planes)); + return std::make_unique( + std::make_unique(std::move(scopedHandle), planes), handle); } PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION diff --git a/src/android/mm/generic_frame_buffer_allocator.cpp b/src/android/mm/generic_frame_buffer_allocator.cpp index 956623df1f80..3750e1bf52a9 100644 --- a/src/android/mm/generic_frame_buffer_allocator.cpp +++ b/src/android/mm/generic_frame_buffer_allocator.cpp @@ -20,6 +20,7 @@ #include "../camera_device.h" #include "../frame_buffer_allocator.h" +#include "../hal_framebuffer.h" using namespace libcamera; @@ -79,7 +80,7 @@ public: ~Private() override; - std::unique_ptr + std::unique_ptr allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage); private: @@ -94,7 +95,7 @@ PlatformFrameBufferAllocator::Private::~Private() gralloc_close(allocDevice_); } -std::unique_ptr +std::unique_ptr PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage) @@ -137,8 +138,10 @@ PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, offset += planeSize; } - return std::make_unique( - std::make_unique(allocDevice_, handle, planes)); + return std::make_unique( + std::make_unique( + allocDevice_, handle, planes), + handle); } PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION From patchwork Mon Jan 16 00:28:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18120 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 22B19BD87C 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 D95D7625E3; Mon, 16 Jan 2023 01:28:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828895; bh=BH0qp987lahQks+3+NQpZk6O5lMQ5d+bavnVhVIkEBo=; 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=JUn0oFHR/DjOgwglG+teek4C6k81R5W1BzxhgxrX9qCGIUPgh6rhDp/1sflvyb6Aa teK0ePzj2/zKHgzOQHdZOhDQRkNF3Goo+ttLKNhmywEBfmXQQorjJaMU1XbUTnfIQN /W0YGDr9OfY1wizpJHMvj+XnVJwHzfh75VlfAIQIf4aAvdbVtYbOvwFFveV6BO4/Bc hy6kyWa6SkfbnaKhaivs5Cp2EtYi8LrNz7dqNLunQ8rlSkoI0Q5aNntZRz525fRt+q 6tWAdUX1ciAbJyEvFB+X6fu2ea5ZoBTt8daQjPYlCeAH8JMUynLFURx9DMLd66QYco DyfraGKH8K7Ag== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 14FF6625E3 for ; Mon, 16 Jan 2023 01:28:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vUD996RK"; 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 8F61E997; Mon, 16 Jan 2023 01:28:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828892; bh=BH0qp987lahQks+3+NQpZk6O5lMQ5d+bavnVhVIkEBo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vUD996RKy6mowft+d40nodzk9xCw5M4FkSPrTWn+JKr/vyYaJb/pumUmOlEZnGOhU w/Z/CXEAAwPGx4RfCTaK6C9xDDqzOPlUQEsHvtUFzkyMUINRqoGbL7cbNs+anBQS3B h2Z8zwjMHfuieeKuZYOv9bxHoLjbXyTbCaw49tMw= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:03 +0200 Message-Id: <20230116002808.16014-4-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 3/8] android: jpeg: Add meson.build in src/android/jpeg 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 further control sources in jpeg to build based on the platform, this patch adds meson.build in src/android/jpeg directory. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Reviewed-by: Han-Lin Chen Signed-off-by: Laurent Pinchart --- src/android/jpeg/meson.build | 8 ++++++++ src/android/meson.build | 5 +---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 src/android/jpeg/meson.build diff --git a/src/android/jpeg/meson.build b/src/android/jpeg/meson.build new file mode 100644 index 000000000000..08397a87bc46 --- /dev/null +++ b/src/android/jpeg/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: CC0-1.0 + +android_hal_sources += files([ + 'encoder_libjpeg.cpp', + 'exif.cpp', + 'post_processor_jpeg.cpp', + 'thumbnailer.cpp' +]) diff --git a/src/android/meson.build b/src/android/meson.build index b543c14371aa..68646120a978 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -47,16 +47,13 @@ android_hal_sources = files([ 'camera_request.cpp', 'camera_stream.cpp', 'hal_framebuffer.cpp', - 'jpeg/encoder_libjpeg.cpp', - 'jpeg/exif.cpp', - 'jpeg/post_processor_jpeg.cpp', - 'jpeg/thumbnailer.cpp', 'yuv/post_processor_yuv.cpp' ]) android_cpp_args = [] subdir('cros') +subdir('jpeg') subdir('mm') android_camera_metadata_sources = files([ 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_; }; 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_; }; From patchwork Mon Jan 16 00:28:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18123 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 9DE8AC3294 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 51B6B625FE; Mon, 16 Jan 2023 01:28:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828898; bh=ljLKoyiQEj8/kbVr0ywJOLhgZoHqygtWF9far7AI1QQ=; 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=aSl9pMbpqQsDKopA2BxPHXGmwhjL80Jzm6HiOegr344/DqDP+uQmGqVyD99spqyjD StqMT5xfh++UUDQXQWMXq6VV3L5+vpY+rdzvor/UrD4ey+pfstLjHInwTjOdKDir5X Qg6pyOB0IEr2HNDU+sX0saHLFcUzO6PPzoC7anuVMND76MWRXzDIsNnpjHxiCC1tiC U65WaAZ0iQ/8Y+hG/kjwSW4iHRaKJbtNc0RumyvZxibFrM5mJxXk3ioSZAxoGvQLsh 4AKOr2UgPAIK/uEvxuXjxa6dCpSPIiSXhWgK/0Nnis6BVYySuWLXkCFdWwttwNLm83 WfcQbvkNpz0fA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 389FC625F0 for ; Mon, 16 Jan 2023 01:28:17 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="l9j4QxRc"; 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 BCA3B9B4; Mon, 16 Jan 2023 01:28:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828897; bh=ljLKoyiQEj8/kbVr0ywJOLhgZoHqygtWF9far7AI1QQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l9j4QxRcbe2FU74lvYMdcxQvfPXRgXixddddYfZND/GU3zEZk/3nN62p24Bi8122+ G3VSSN6VeMsRhKDSDoYgqGoLcGt32MD9Zsu6gHgy+R0zoUvkgn/gFoFzEC9Z9XlbLG V0IE1mimlyRIeSlI+wCqrVUCFUmk6ZNPrL6+5/+4= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:06 +0200 Message-Id: <20230116002808.16014-7-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 6/8] android: jpeg: Return an error code from generateThumbnail() 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" The usual way to signal errors in libcamera is to return an error code. Change the Encoder::generateThumbnail() function to return an int instead of signaling errors by not resizing the thumbnail vector. This allows propagating error codes to the callers. Signed-off-by: Laurent Pinchart --- src/android/jpeg/encoder.h | 8 +-- src/android/jpeg/encoder_libjpeg.cpp | 70 +++++++++++++----------- src/android/jpeg/encoder_libjpeg.h | 8 +-- src/android/jpeg/post_processor_jpeg.cpp | 6 +- 4 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index 5f9ef890023a..d15f22e67830 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -22,8 +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; + virtual int 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 9bbf1abbe09c..8f4df7899dfd 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -89,53 +89,57 @@ int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, return captureEncoder_.encode(frame.planes(), dest, exifData, quality); } -void EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source, - const libcamera::Size &targetSize, - unsigned int quality, - std::vector *thumbnail) +int EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) { /* Stores the raw scaled-down thumbnail bytes. */ std::vector rawThumbnail; thumbnailer_.createThumbnail(source, targetSize, &rawThumbnail); + if (rawThumbnail.empty()) + return -EINVAL; StreamConfiguration thCfg; thCfg.size = targetSize; thCfg.pixelFormat = thumbnailer_.pixelFormat(); int ret = thumbnailEncoder_.configure(thCfg); + if (ret) + return ret; - if (!rawThumbnail.empty() && !ret) { - /* - * \todo Avoid value-initialization of all elements of the - * vector. - */ - thumbnail->resize(rawThumbnail.size()); + /* + * \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 }); + /* + * 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); + int jpegSize = thumbnailEncoder_.encode(thumbnailPlanes, *thumbnail, + {}, quality); + thumbnail->resize(jpegSize); - LOG(JPEG, Debug) - << "Thumbnail compress returned " - << jpegSize << " bytes"; - } + LOG(JPEG, Debug) + << "Thumbnail compress returned " + << jpegSize << " bytes"; + + return 0; } EncoderLibJpeg::Encoder::Encoder() diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index a022a72e02bf..9cff4f1b42e3 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -28,10 +28,10 @@ public: libcamera::Span destination, libcamera::Span exifData, unsigned int quality) override; - void generateThumbnail(const libcamera::FrameBuffer &source, - const libcamera::Size &targetSize, - unsigned int quality, - std::vector *thumbnail) override; + int generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) override; private: class Encoder diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 69b18a2e5945..5df89383e1af 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -115,9 +115,9 @@ void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBu if (thumbnailSize != Size(0, 0)) { std::vector thumbnail; - encoder_->generateThumbnail(source, thumbnailSize, - quality, &thumbnail); - if (!thumbnail.empty()) + ret = encoder_->generateThumbnail(source, thumbnailSize, + quality, &thumbnail); + if (!ret) exif.setThumbnail(std::move(thumbnail), Exif::Compression::JPEG); } From patchwork Mon Jan 16 00:28:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18124 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 298A2BD87C for ; Mon, 16 Jan 2023 00:28:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D75FE625EF; Mon, 16 Jan 2023 01:28:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828900; bh=6Bsg9cgMployM9UcfkXKPXFJldYQPlYqaB0ftDOCHqI=; 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=izzBIIbdKfk3gnaKWBjZkNKzg4bKRyMzLqXwcPbCUasmQs3OQaTC3iNkRNX0+YFBL VnzVTgexBGGw66W/mGy6CV0bJfvgkMGONZeKKony7XqfIYLRqwKtUjteApPN8vt6uu tS2MmFmWDywC1TD/WOjCr9cxOb5brbEUeUt3WO7pBOoFhgZbV1tjoIxo09ABN0MT/c 4o7/+SHllQPgkE5kNR+Ca4uxUygxQxVEDhP6hWtah3GttqjCjRyUn5gsmYfkICQguY 5SX0zweUDkTeKwMXpl33IPkkko1IJ2pvuQ1iKNcayMOMAsq1X31y6idwjvz4M3tgvv 9hm3Ou66R3KiA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E2A5625F0 for ; Mon, 16 Jan 2023 01:28:18 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VlemsUnr"; 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 1F051997; Mon, 16 Jan 2023 01:28:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828898; bh=6Bsg9cgMployM9UcfkXKPXFJldYQPlYqaB0ftDOCHqI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VlemsUnrOdTqLWZU+8+2NGpjKzVQOamMtCJ3sgo0KrCe9qHXLQm2QEyBsAZbXEZLC eN2RhOCaDZfTynkZMM9mZQOWwqKHGhbV3U3d1wZJcCRiMnSPkBP3Z27I0puvyF7GJZ kkbEZIXhLdEY1gUoxQGclZ713tSj0rPsswyFGMU0= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:07 +0200 Message-Id: <20230116002808.16014-8-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 7/8] android: jpeg: Pass StreamBuffer to Encoder::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 To prepare for support of the JEA encoder in a following commit, which will need to access the buffer_handle_t of the destination buffer, pass the StreamBuffer to the Encoder::encoder() function. As the StreamBuffer contains the source FrameBuffer and the destination Span, drop them from the function arguments and access them directly from the StreamBuffer. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart Reviewed-by: Han-Lin Chen Signed-off-by: Laurent Pinchart --- src/android/jpeg/encoder.h | 5 +++-- src/android/jpeg/encoder_libjpeg.cpp | 15 ++++++++++----- src/android/jpeg/encoder_libjpeg.h | 3 +-- src/android/jpeg/post_processor_jpeg.cpp | 3 +-- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index d15f22e67830..d73cafba099d 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -12,14 +12,15 @@ #include #include +#include "../camera_request.h" + class Encoder { public: virtual ~Encoder() = default; virtual int configure(const libcamera::StreamConfiguration &cfg) = 0; - virtual int encode(const libcamera::FrameBuffer &source, - libcamera::Span destination, + virtual int encode(Camera3RequestDescriptor::StreamBuffer *buffer, libcamera::Span exifData, unsigned int quality) = 0; virtual int generateThumbnail(const libcamera::FrameBuffer &source, diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index 8f4df7899dfd..c2fdc37770e5 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -24,6 +24,8 @@ #include "libcamera/internal/formats.h" #include "libcamera/internal/mapped_framebuffer.h" +#include "../camera_buffer.h" + using namespace libcamera; LOG_DECLARE_CATEGORY(JPEG) @@ -76,17 +78,20 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg) return captureEncoder_.configure(cfg); } -int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, - Span exifData, unsigned int quality) +int EncoderLibJpeg::encode(Camera3RequestDescriptor::StreamBuffer *buffer, + libcamera::Span exifData, + unsigned int quality) { - MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); + MappedFrameBuffer frame(buffer->srcBuffer, + MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { - LOG(JPEG, Error) << "Failed to map FrameBuffer: " + LOG(JPEG, Error) << "Failed to map FrameBuffer : " << strerror(frame.error()); return frame.error(); } - return captureEncoder_.encode(frame.planes(), dest, exifData, quality); + return captureEncoder_.encode(frame.planes(), buffer->dstBuffer->plane(0), + exifData, quality); } int EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source, diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 9cff4f1b42e3..d770595a495c 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -24,8 +24,7 @@ public: ~EncoderLibJpeg(); int configure(const libcamera::StreamConfiguration &cfg) override; - int encode(const libcamera::FrameBuffer &source, - libcamera::Span destination, + int encode(Camera3RequestDescriptor::StreamBuffer *buffer, libcamera::Span exifData, unsigned int quality) override; int generateThumbnail(const libcamera::FrameBuffer &source, diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 5df89383e1af..2a22b4a88f4a 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -146,8 +146,7 @@ void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBu const uint8_t quality = ret ? *entry.data.u8 : 95; resultMetadata->addEntry(ANDROID_JPEG_QUALITY, quality); - int jpeg_size = encoder_->encode(source, destination->plane(0), - exif.data(), quality); + int jpeg_size = encoder_->encode(streamBuffer, exif.data(), quality); if (jpeg_size < 0) { LOG(JPEG, Error) << "Failed to encode stream image"; processComplete.emit(streamBuffer, PostProcessor::Status::Error); From patchwork Mon Jan 16 00:28:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 18125 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 BC302C3294 for ; Mon, 16 Jan 2023 00:28:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5D2A2625EC; Mon, 16 Jan 2023 01:28:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1673828901; bh=4eAWDyIXyZYGJ7WwvcqGEf9HQqfFtULkt2N066/wd2c=; 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=Vcxlnj6AP8YuOGpduFxJQr1YgI2k04o4jjXejb4KEhYAShElc6TrjRt2QHRnfcLw+ FIu14T4tqgttu/BHb1VfLTSfUXx7cEOnq3+o5oE4zviwAqwAx67gSdj1jDa0kWLQGj IZiR2Mc18OV7qkq6y0QYyRtXrLTg58quQcLyJag6SlgSUKCzQIDADsuyZJLrw0yuWk 3djrXQhromRLg80Df7gLZD2gHA9Fr2uWILPt3HuXvbWBFYhVxlJpcL49DwfiRPNOuD 5MB2yncOhpuIhtD/TWcd8RGaKr8LjjBoGWizA+w/qsWuYVj4LHdDJSiy43NiY6iFo/ SOtLKBLhcec6w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E869D625EC for ; Mon, 16 Jan 2023 01:28:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="aeX0E3Tq"; 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 75D53997; Mon, 16 Jan 2023 01:28:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1673828899; bh=4eAWDyIXyZYGJ7WwvcqGEf9HQqfFtULkt2N066/wd2c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aeX0E3TqpLifv7ykAZ7CjWCa6CwJyFA6G1BWUKzhJe6sIWw5DDAYagBQpWIM4OTXr 6cOCmw6oPPnojAb15bA5/XfdopLlTYhp4nvB3pSS3YP38iEz+qBY2fkd5M9XY3U5v1 YfCEtN6hyqH9uOg+21NQnNLXk/uGBNMnn62pyTG0= To: libcamera-devel@lists.libcamera.org Date: Mon, 16 Jan 2023 02:28:08 +0200 Message-Id: <20230116002808.16014-9-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 8/8] android: jpeg: Add JEA implementation 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 This patch adds JEA implementation to replace libjpeg in CrOS platform, where hardware accelerator is available. Signed-off-by: Harvey Yang --- src/android/cros/camera3_hal.cpp | 4 +- src/android/cros_mojo_token.h | 12 +++ src/android/jpeg/encoder_jea.cpp | 103 +++++++++++++++++++++++ src/android/jpeg/encoder_jea.h | 35 ++++++++ src/android/jpeg/meson.build | 13 ++- src/android/jpeg/post_processor_jpeg.cpp | 8 ++ 6 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 src/android/cros_mojo_token.h create mode 100644 src/android/jpeg/encoder_jea.cpp create mode 100644 src/android/jpeg/encoder_jea.h diff --git a/src/android/cros/camera3_hal.cpp b/src/android/cros/camera3_hal.cpp index fb863b5f9aa9..71acb441b0d4 100644 --- a/src/android/cros/camera3_hal.cpp +++ b/src/android/cros/camera3_hal.cpp @@ -8,9 +8,11 @@ #include #include "../camera_hal_manager.h" +#include "../cros_mojo_token.h" -static void set_up([[maybe_unused]] cros::CameraMojoChannelManagerToken *token) +static void set_up(cros::CameraMojoChannelManagerToken *token) { + gCrosMojoToken = token; } static void tear_down() diff --git a/src/android/cros_mojo_token.h b/src/android/cros_mojo_token.h new file mode 100644 index 000000000000..043c752a3997 --- /dev/null +++ b/src/android/cros_mojo_token.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * cros_mojo_token.h - cros-specific mojo token + */ + +#pragma once + +#include + +inline cros::CameraMojoChannelManagerToken *gCrosMojoToken = nullptr; diff --git a/src/android/jpeg/encoder_jea.cpp b/src/android/jpeg/encoder_jea.cpp new file mode 100644 index 000000000000..a7076039d0b7 --- /dev/null +++ b/src/android/jpeg/encoder_jea.cpp @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * encoder_jea.cpp - JPEG encoding using CrOS JEA + */ + +#include "encoder_jea.h" + +#include "libcamera/internal/mapped_framebuffer.h" + +#include + +#include "../cros_mojo_token.h" +#include "../hal_framebuffer.h" + +EncoderJea::EncoderJea() = default; + +EncoderJea::~EncoderJea() = default; + +int EncoderJea::configure(const libcamera::StreamConfiguration &cfg) +{ + size_ = cfg.size; + + if (jpegCompressor_) + return 0; + + if (gCrosMojoToken == nullptr) + return -ENOTSUP; + + jpegCompressor_ = cros::JpegCompressor::GetInstance(gCrosMojoToken); + + return 0; +} + +int EncoderJea::encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer, + libcamera::Span exifData, + unsigned int quality) +{ + if (!jpegCompressor_) + return -ENOTSUP; + + uint32_t outDataSize = 0; + const HALFrameBuffer *fb = + dynamic_cast(streamBuffer->srcBuffer); + + if (!jpegCompressor_->CompressImageFromHandle(fb->handle(), + *streamBuffer->camera3Buffer, + size_.width, size_.height, + quality, exifData.data(), + exifData.size(), + &outDataSize)) + return -EBUSY; + + return outDataSize; +} + +int EncoderJea::generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) +{ + if (!jpegCompressor_) + return -ENOTSUPP; + + libcamera::MappedFrameBuffer frame(&source, + libcamera::MappedFrameBuffer::MapFlag::Read); + + if (frame.planes().empty()) + return -EINVAL; + + /* JEA needs consecutive memory. */ + unsigned long size = 0, index = 0; + for (const auto &plane : frame.planes()) + size += plane.size(); + + std::vector data(size); + for (const auto &plane : frame.planes()) { + memcpy(&data[index], plane.data(), plane.size()); + index += plane.size(); + } + + uint32_t outDataSize = 0; + + /* + * Since the structure of the App1 segment is like: + * 0xFF [1 byte marker] [2 bytes size] [data] + * And it should not be larger than 64K. + */ + constexpr int kApp1MaxDataSize = 65532; + thumbnail->resize(kApp1MaxDataSize); + + if (!jpegCompressor_->GenerateThumbnail(data.data(), + size_.width, size_.height, + targetSize.width, + targetSize.height, quality, + thumbnail->size(), + thumbnail->data(), + &outDataSize)) + return -EBUSY; + + thumbnail->resize(outDataSize); +} diff --git a/src/android/jpeg/encoder_jea.h b/src/android/jpeg/encoder_jea.h new file mode 100644 index 000000000000..2eba31c2f73c --- /dev/null +++ b/src/android/jpeg/encoder_jea.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * encoder_jea.h - JPEG encoding using CrOS JEA + */ + +#pragma once + +#include + +#include + +#include "encoder.h" + +class EncoderJea : public Encoder +{ +public: + EncoderJea(); + ~EncoderJea(); + + int configure(const libcamera::StreamConfiguration &cfg) override; + int encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer, + libcamera::Span exifData, + unsigned int quality) override; + int generateThumbnail(const libcamera::FrameBuffer &source, + const libcamera::Size &targetSize, + unsigned int quality, + std::vector *thumbnail) override; + +private: + libcamera::Size size_; + + std::unique_ptr jpegCompressor_; +}; diff --git a/src/android/jpeg/meson.build b/src/android/jpeg/meson.build index 08397a87bc46..2b68f54c4228 100644 --- a/src/android/jpeg/meson.build +++ b/src/android/jpeg/meson.build @@ -1,8 +1,17 @@ # SPDX-License-Identifier: CC0-1.0 android_hal_sources += files([ - 'encoder_libjpeg.cpp', 'exif.cpp', 'post_processor_jpeg.cpp', - 'thumbnailer.cpp' ]) + +platform = get_option('android_platform') +if platform == 'generic' + android_hal_sources += files([ + 'encoder_libjpeg.cpp', + 'thumbnailer.cpp' + ]) +elif platform == 'cros' + android_hal_sources += files(['encoder_jea.cpp']) + android_deps += [dependency('libcros_camera')] +endif diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 2a22b4a88f4a..f7cc70de1ef1 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -12,7 +12,11 @@ #include "../camera_device.h" #include "../camera_metadata.h" #include "../camera_request.h" +#if defined(OS_CHROMEOS) +#include "encoder_jea.h" +#else /* !defined(OS_CHROMEOS) */ #include "encoder_libjpeg.h" +#endif #include "exif.h" #include @@ -44,7 +48,11 @@ int PostProcessorJpeg::configure(const StreamConfiguration &inCfg, streamSize_ = outCfg.size; +#if defined(OS_CHROMEOS) + encoder_ = std::make_unique(); +#else /* !defined(OS_CHROMEOS) */ encoder_ = std::make_unique(); +#endif return encoder_->configure(inCfg); }