From patchwork Thu Dec 1 09:27:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17923 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 253D5BDE6B for ; Thu, 1 Dec 2022 09:27:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D376463343; Thu, 1 Dec 2022 10:27:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886866; bh=aRrFmXPG74P5jR3qMonxndloJ1Z2J/TPA6FbyfrdHlo=; 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=DIhPTOHl64nvrJPLUvRwyu2dd6737OtPcU+YANoNHD5vVzJ/8hm9fw6s4lWdl97Vo B2pJjNIiM2l5UMdz82BSccaAxbkAN78/Lz8lYW6H2a6DKP/k2opAfRQnAfhANo2854 xeZ5xteKB8KwTDJhB1QMLD+HQGVXCWvlasYXTLGgHwnI3pfgUwCRJigo1miJbCjJ5R S/zyizF+fiBHNHtsUvnwuL2BT0yEkY1AhVzFJK5iqE4zc3LZNAwqjbZR3utm5nxb6u SL9QAO8USzOUAJwpWLJtpht9UO/tx8Kf4oVzslkhYDzqTTrNJpou17XK+2ZoBnwUNP hFX/PkzOzfZCw== Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 09A6C63335 for ; Thu, 1 Dec 2022 10:27:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="a1ZAAbek"; dkim-atps=neutral Received: by mail-pf1-x42d.google.com with SMTP id 140so1324653pfz.6 for ; Thu, 01 Dec 2022 01:27:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5ODVHMsyA8hsFxgiWC634xNltO+LzlfKNEkD4YkrXuI=; b=a1ZAAbekUe7Yq3EyeK3z2q3fiQjQa2Qf4MscgwAy9X1hJReJyk4+F9CkoCRKxvOEGZ NBjjLQxHDYeBET5cHK6wRUmA7GdXQcrgWRVUOfr9SYTW11x6kheHAy6DgMYI8EIOk70f 6tntV4ZLxNz76YJOasH0+PvuXeZQvcZBXowuQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5ODVHMsyA8hsFxgiWC634xNltO+LzlfKNEkD4YkrXuI=; b=j4i6aTrd2dZNz/3+94xAnA49hyQLT6N8V/zIs3InooH8z4n5yVXgv2QlFY2WCRKyNK QMvF6HOSZYU1GTzY7epBgTLZGbUL1ruN6wmC54bj8NNm/UDNSGC1nItyM8momRgmXQiq CjwlWqUBXQxX1km3Q70uB1sqqzduEmfWpJf6g+5XAmxx84dwciiVr9PtBavnDK7xIgMR 8xCF4o9KL06IIvf4SJsLSUmR3i7d5lBmspu8NaKqIwg0CIVqf1QUuYwX7j3ED2YMXnbB m++KOPGx34300/BICYUKN+NicIKdsqOXCLsBoNxt9mDnAGWQwqEG7SJQUgfzVLeSrXBR HBbg== X-Gm-Message-State: ANoB5pm7msA5T9/a1ux1XCn5m/5zL8PSg3Ryo8OfkMaRh/jAqA3MA25m QyfYu3ehvTNRqPsFIfcRL7+w9TAEmcyUjg== X-Google-Smtp-Source: AA0mqf58e9hRjN3kq6aCoankmLTfJMpCD6P86T++UlyzrLQRaDG6WLBUpSkiRkHIGuJYJEbSGK2A3Q== X-Received: by 2002:a63:d751:0:b0:46f:f87c:fb1a with SMTP id w17-20020a63d751000000b0046ff87cfb1amr42794515pgi.214.1669886862230; Thu, 01 Dec 2022 01:27:42 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:41 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:28 +0000 Message-Id: <20221201092733.2042078-2-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 1/6] 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang 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 --- 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 69553999..61244829 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 Thu Dec 1 09:27:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17924 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 23E0FC3284 for ; Thu, 1 Dec 2022 09:27:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 67AD26333E; Thu, 1 Dec 2022 10:27:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886867; bh=yBofSPsRWhqy1SHwJL6wRgxHfkNtSapeoFSfzmk7Vhc=; 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=CQpz6r42u57EYpNwZJMQL6rgchGGMxvQlaCE+bLMEibwii+lRQNseGtB9GdfTp3D4 Y85DgV7Y0+fCq3sK+kVqJ53cG/NNcde4rhJg+Vfrixq0Am0Ia4N++Qe9+QxpofN5FC e4L2bt34n0LDLNJQ/E8ESjpVbosMhsHy7QeQzQ+8YeXP4rMyiqcDUVCgn5HdAomiUt Ut/qqPg28YroKKdw9WBFpPRJAfEsMycj47ahAMBhf9JMSu+V9ki2H4vFFHzreg2xbA r2zkm2CUR5DhgOZ+SoEvQdvRcccdN5DwT+NaBXQ4dnHhlzO6w5jqkW4ziGPWm98bqJ rt4TnWjLng6PA== Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A071063335 for ; Thu, 1 Dec 2022 10:27:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="XQeqZILb"; dkim-atps=neutral Received: by mail-pf1-x431.google.com with SMTP id l127so683442pfl.2 for ; Thu, 01 Dec 2022 01:27:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2WIVjXf7T7zWWY8SH7R+GpLPzdRSVC2JpAFQv8b5zVI=; b=XQeqZILbGCM+Qr6KmEk3XILbr1nV7Lrym2wr265Wyff2Dj3ry6VA8S6lW1MZY6VmT2 dHqFIX/R9xKEt0cPWEJ8jW7dUbkWuGQhtNXvD4Zg6tdg/KQ2W94W3THs/psQdBl7NY1R 7gHXVlE+iTaGsUxWMEs9qWHsq/IKK6PN323go= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2WIVjXf7T7zWWY8SH7R+GpLPzdRSVC2JpAFQv8b5zVI=; b=vdEkNXGptJHi76m/ZKs0relaOzvS7GKAzkYDu6LsajJR4JaiqdfjRQPVlBpDOSJSw+ 7lT9hXjKY5XFKNgRFEvZ/ypCrd0U/RiGEZF5NPuU35YklXCJXrExSj5HbP7D9ojX9t5g vEoumZrwqsuQltNf/c+eoJL5YEms82zB9SWgHG6zgyuHguuUInUD9Q27bod1FCjO2pmF UKppqrY/++CUQJZ8Bhhi4pTt3hmmwwJCTP5wHiBSQ2SJ+CeYv+zaneW4/KGG1ZrfDXB4 Z1LYJSix156VLEu1Wq9pNaBo+QswVbLAlWeGIKtE1PQ1i8rbRTqCGnkb9oQWJ76DeoD+ 3LbQ== X-Gm-Message-State: ANoB5pmAElrDfFUK4leF/2jCAF90jBr9ckcI7cqME8HEEBNhEPFtl5Cs NYWXJB4iVIOSdsqomiwbTDFIKCuBDmwNR8Uf X-Google-Smtp-Source: AA0mqf48xgkM9+cCpBBEeEOpHAHx0/Z8jtr5m5SjLrEVSx2PUYGRHs1ikrj8F5krW2dslr6+kmeHyQ== X-Received: by 2002:a65:4c42:0:b0:477:f872:8b6 with SMTP id l2-20020a654c42000000b00477f87208b6mr23000323pgr.457.1669886863555; Thu, 01 Dec 2022 01:27:43 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:43 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:29 +0000 Message-Id: <20221201092733.2042078-3-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 2/6] Add HALFrameBuffer and replace FrameBuffer in src/android 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang AndroidFrameBuffer 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 --- src/android/camera_device.cpp | 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 +++++--- 7 files changed, 67 insertions(+), 12 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 b20e389b..872161ba 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; @@ -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/frame_buffer_allocator.h b/src/android/frame_buffer_allocator.h index 5d2eeda1..e5c94922 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 00000000..4ac5a820 --- /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 - Android 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 00000000..ec737e70 --- /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 - Android 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 1bba54de..c2773f9e 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -37,6 +37,7 @@ endif android_deps += [libyuv_dep] android_hal_sources = files([ + 'hal_framebuffer.cpp', 'camera3_hal.cpp', 'camera_capabilities.cpp', 'camera_device.cpp', diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp index 0665c77b..0a5c59f2 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 956623df..3750e1bf 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 Thu Dec 1 09:27:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17925 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 34C66BDE6B for ; Thu, 1 Dec 2022 09:27:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E687263343; Thu, 1 Dec 2022 10:27:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886870; bh=UPOmV2/pLVkob/lRridfR7w3io4o2Nf0IbjP2qlbWSc=; 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=cn8pyjF4YmdBWJtil85V4GLpvqdqgmTynozd0cjHnpnBCoU1lHTnFQqricKhYqhvW +X6jRx/06IXMbpFPuqlBq8+hj7JMS2pUlbLxnpLJ/DDaL2RIFXqN28wvlMM1eHL6CO CdFBw4rXssRcQa9D1PjZJjubXgSokvrNqZ9jceOxSEORgPFuui/C8EmUT9E+Re2fJk 63hGkyXMtKYUuPcEqOMMVdIKkRdNAYZ9t5zlNSwn2q1/ehqvFLJCUIb451F6aLOxZl DzYvR/EmAPUjKmsVT0v8yoIVzbCd2P7wLd4riwrORPX/QLapQ+0J5a3shOTYd6/kq2 D+L+rxJE+qIcg== Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C714963336 for ; Thu, 1 Dec 2022 10:27:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="OWtC5r2i"; dkim-atps=neutral Received: by mail-pl1-x631.google.com with SMTP id k7so1092810pll.6 for ; Thu, 01 Dec 2022 01:27:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Q2dB9naBSLEma6JK3Mn8HFXDh9wGTE/pYpWJDWXPs4Q=; b=OWtC5r2ihVL1sL64TBCo0ZM/HABWTnpHJj1DpKowZSIInW9j5JhPFBnmNtFOQlOqTs TBzZIkbF9Y++gAX5gEqu4ZUOH8dbkcV2Q9dMDuTEIlrHw0XxpIbup2yVLYzIexPUUYME PWMM6rRktBnqd3MiyBZNRuwkhos7vV98Ow8hk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q2dB9naBSLEma6JK3Mn8HFXDh9wGTE/pYpWJDWXPs4Q=; b=w4Es3dcAwzRjUMJQEkSorWsejP311kC2Jhn73dYZ9WSOpjD4vuSnulH3TGOhbMD59j Vypu3ssIm4zuTlarV5n+tAqHSrVGngCnK9ZHD0EUhzw5Kf9NsVyDXtF5goB2ymWGRjeL eIsvEGv4wCqHxkHZcvFVVagv5gzf5zsX22HglK/44r42H4LaH4aEepaXFvJvxP78CjYF yseUQMeSMoOnQ5EPRmxXWv4t/B6JZy+NKiqZzuZLqMqVvAwu5j78YG/TVeXWtFy0y4gJ FocnmbVSZiRoEObVZ8nRiQee8Nzn2xa8PWE53tIabLtGhs2thDi1YsyO9jLs6Q1zFQqs Dxdg== X-Gm-Message-State: ANoB5pn6hBvbnT5GNTh3QbtGDsJv2zKAnPi4NJubC0E/KmyMp5WEpLUl 32VhLRfVC5tiR070eQAqM1YMWCJL6tudvA6w X-Google-Smtp-Source: AA0mqf6+2wNBbYf+OiUAKK7RN/JBSjUCv6xnZy9dDE7doO4pFeyPbMsoCDT3UhwJB6i0bP6Z6lBYpA== X-Received: by 2002:a17:902:b7c3:b0:189:5e92:d45a with SMTP id v3-20020a170902b7c300b001895e92d45amr34241514plz.157.1669886864986; Thu, 01 Dec 2022 01:27:44 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:44 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:30 +0000 Message-Id: <20221201092733.2042078-4-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 3/6] 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang 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 --- 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 00000000..08397a87 --- /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 c2773f9e..b24e2e52 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -47,16 +47,13 @@ android_hal_sources = files([ 'camera_ops.cpp', 'camera_request.cpp', 'camera_stream.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 Thu Dec 1 09:27:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17926 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 CE83EC3284 for ; Thu, 1 Dec 2022 09:27:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8ACCC63345; Thu, 1 Dec 2022 10:27:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886870; bh=Z5msnFGTDVHbIG7OKAF2z9RNv9X6UVpxLCMk5dyA1kE=; 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=eG0G9jJBzuA45YSpr3eQI2IBN/PcxttjNt2q4jN99d7MiebxqNAtjX9XBQ7NAXJHG uZu+c5ikX9SH4Gjsx76fh3YT+AIXGHP6IhNs7yUBhatW+h5p2qLYYsms5Qw3CmbxsO eZJlSxkosbCpLm2/DQ20D2/5+JBKXjPUKMtsxpr8rtJwhESpxiKfThddFYrJJucr+9 kxEaY67syKtDmRyU00K4kM+qLVzhK1718BWpahwmpxgfdSONQiQtyand83fTHZ57jH +zuxdQlzEayX50FLBEee8fNyoJem92ZOvXNhHfeIdBMxOKo9hQ/bCSUM9Nad08MUGr 5bB1NJkEiNXog== Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8C1E363336 for ; Thu, 1 Dec 2022 10:27:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="OmTjnt8P"; dkim-atps=neutral Received: by mail-pf1-x435.google.com with SMTP id z17so1344222pff.1 for ; Thu, 01 Dec 2022 01:27:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GppenPRfYE9AngDAbvr9EW4YaLp/osn673u8/Q+g9zI=; b=OmTjnt8PoPHnUybMEwHPsc4if0S4Q9Ker5ri3dR/3QeSx40U4446fCnygfWUkH9eZ8 2UXNWb549AWxsO5GZliW0Y0zejAJwmTNw2jvKZ0s5AJHruUkz5otlma5KS9qbIwvvvsc 4EY1nJZtefNKEVRuZspLZPToIhifLh6O16+gQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GppenPRfYE9AngDAbvr9EW4YaLp/osn673u8/Q+g9zI=; b=xXYZVCs/wWb/1KHpef9A/a5tiGHncTkOAkmKWBSyaguF7U46SlsJoA3GAd4AmNSefY z5slT4HNz2ElaVzzgeWj7+N8hk3jwD4sqp7rMCEjRSWlZsVbXw6vvicQSRl1m1sGoEAe rSwXAY2FEvwZlpmgwPJQAOpxJtn2gVVVjQLl/JeRX21yrQbfZQem6tFrIZ3XFgOjMWKd AiwaRhxgkFMQm2dA++0eqT9swRqnjgnSCkiooof1eSfnQ/Bv9WaNBC5DiCYHtKiITL4V 4WMK6q32suQSjE4RJ+vBluGIqn3S0IMd3v7YDG1FxPvqlkNh03gBzSNGNk122y6OIM6m exqA== X-Gm-Message-State: ANoB5pm6Fl21IrOjAwiHRbZGBTJq4kIJE2Ik/OhleLSPV2PHSIn256lk qqYwzFFUs1OdI0KKtNJvyDYLrIeDqkMBB594 X-Google-Smtp-Source: AA0mqf6SsrDN2eOU+sRt8bPL8mFcLriaLrJaBEmS4BT56WPRfOhh1WHQ/zP7KRNFAR23g3ghz/aJ1A== X-Received: by 2002:a63:d117:0:b0:476:c781:d3ae with SMTP id k23-20020a63d117000000b00476c781d3aemr40493070pgg.183.1669886866648; Thu, 01 Dec 2022 01:27:46 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:46 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:31 +0000 Message-Id: <20221201092733.2042078-5-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 4/6] 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang 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 --- src/android/jpeg/encoder.h | 5 + src/android/jpeg/encoder_libjpeg.cpp | 122 ++++++++++++++++++----- src/android/jpeg/encoder_libjpeg.h | 28 +++++- src/android/jpeg/post_processor_jpeg.cpp | 54 +--------- src/android/jpeg/post_processor_jpeg.h | 11 +- 5 files changed, 130 insertions(+), 90 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index b974d367..7dc1ee27 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -22,4 +22,9 @@ public: libcamera::Span destination, libcamera::Span exifData, unsigned int quality) = 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 fd62bd9c..cc37fde3 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -71,29 +71,43 @@ const struct JPEGPixelFormatInfo &findPixelInfo(const PixelFormat &format) EncoderLibJpeg::EncoderLibJpeg() { /* \todo Expand error handling coverage with a custom handler. */ - compress_.err = jpeg_std_error(&jerr_); + image_data_.compress.err = jpeg_std_error(&image_data_.jerr); + thumbnail_data_.compress.err = jpeg_std_error(&thumbnail_data_.jerr); - jpeg_create_compress(&compress_); + jpeg_create_compress(&image_data_.compress); + jpeg_create_compress(&thumbnail_data_.compress); } EncoderLibJpeg::~EncoderLibJpeg() { - jpeg_destroy_compress(&compress_); + jpeg_destroy_compress(&image_data_.compress); + jpeg_destroy_compress(&thumbnail_data_.compress); } int EncoderLibJpeg::configure(const StreamConfiguration &cfg) { - const struct JPEGPixelFormatInfo info = findPixelInfo(cfg.pixelFormat); + thumbnailer_.configure(cfg.size, cfg.pixelFormat); + + return configureEncoder(&image_data_.compress, cfg.pixelFormat, + cfg.size); +} + +int EncoderLibJpeg::configureEncoder(struct jpeg_compress_struct *compress, + libcamera::PixelFormat pixelFormat, + libcamera::Size size) +{ + const struct JPEGPixelFormatInfo info = findPixelInfo(pixelFormat); + if (info.colorSpace == JCS_UNKNOWN) return -ENOTSUP; - compress_.image_width = cfg.size.width; - compress_.image_height = cfg.size.height; - compress_.in_color_space = info.colorSpace; + compress->image_width = size.width; + compress->image_height = size.height; + compress->in_color_space = info.colorSpace; - compress_.input_components = info.colorSpace == JCS_GRAYSCALE ? 1 : 3; + compress->input_components = info.colorSpace == JCS_GRAYSCALE ? 1 : 3; - jpeg_set_defaults(&compress_); + jpeg_set_defaults(compress); pixelFormatInfo_ = &info.pixelFormatInfo; @@ -107,13 +121,13 @@ void EncoderLibJpeg::compressRGB(const std::vector> &planes) { unsigned char *src = const_cast(planes[0].data()); /* \todo Stride information should come from buffer configuration. */ - unsigned int stride = pixelFormatInfo_->stride(compress_.image_width, 0); + unsigned int stride = pixelFormatInfo_->stride(compress_->image_width, 0); JSAMPROW row_pointer[1]; - while (compress_.next_scanline < compress_.image_height) { - row_pointer[0] = &src[compress_.next_scanline * stride]; - jpeg_write_scanlines(&compress_, row_pointer, 1); + while (compress_->next_scanline < compress_->image_height) { + row_pointer[0] = &src[compress_->next_scanline * stride]; + jpeg_write_scanlines(compress_, row_pointer, 1); } } @@ -123,7 +137,7 @@ void EncoderLibJpeg::compressRGB(const std::vector> &planes) */ void EncoderLibJpeg::compressNV(const std::vector> &planes) { - uint8_t tmprowbuf[compress_.image_width * 3]; + uint8_t tmprowbuf[compress_->image_width * 3]; /* * \todo Use the raw api, and only unpack the cb/cr samples to new line @@ -133,10 +147,10 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) * Possible hints at: * https://sourceforge.net/p/libjpeg/mailman/message/30815123/ */ - unsigned int y_stride = pixelFormatInfo_->stride(compress_.image_width, 0); - unsigned int c_stride = pixelFormatInfo_->stride(compress_.image_width, 1); + unsigned int y_stride = pixelFormatInfo_->stride(compress_->image_width, 0); + unsigned int c_stride = pixelFormatInfo_->stride(compress_->image_width, 1); - unsigned int horzSubSample = 2 * compress_.image_width / c_stride; + unsigned int horzSubSample = 2 * compress_->image_width / c_stride; unsigned int vertSubSample = pixelFormatInfo_->planes[1].verticalSubSampling; unsigned int c_inc = horzSubSample == 1 ? 2 : 0; @@ -149,14 +163,14 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) JSAMPROW row_pointer[1]; row_pointer[0] = &tmprowbuf[0]; - for (unsigned int y = 0; y < compress_.image_height; y++) { + for (unsigned int y = 0; y < compress_->image_height; y++) { unsigned char *dst = &tmprowbuf[0]; const unsigned char *src_y = src + y * y_stride; const unsigned char *src_cb = src_c + (y / vertSubSample) * c_stride + cb_pos; const unsigned char *src_cr = src_c + (y / vertSubSample) * c_stride + cr_pos; - for (unsigned int x = 0; x < compress_.image_width; x += 2) { + for (unsigned int x = 0; x < compress_->image_width; x += 2) { dst[0] = *src_y; dst[1] = *src_cb; dst[2] = *src_cr; @@ -174,13 +188,67 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) dst += 3; } - jpeg_write_scanlines(&compress_, row_pointer, 1); + jpeg_write_scanlines(compress_, row_pointer, 1); } } +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); + + int ret = configureEncoder(&thumbnail_data_.compress, + thumbnailer_.pixelFormat(), targetSize); + compress_ = &thumbnail_data_.compress; + + 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 = encode(thumbnailPlanes, *thumbnail, {}, + quality); + thumbnail->resize(jpeg_size); + + LOG(JPEG, Debug) + << "Thumbnail compress returned " + << jpeg_size << " bytes"; + + return jpeg_size; + } + + return -1; +} + int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, Span exifData, unsigned int quality) { + compress_ = &image_data_.compress; + MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { LOG(JPEG, Error) << "Failed to map FrameBuffer : " @@ -198,7 +266,7 @@ int EncoderLibJpeg::encode(const std::vector> &src, unsigned char *destination = dest.data(); unsigned long size = dest.size(); - jpeg_set_quality(&compress_, quality, TRUE); + jpeg_set_quality(compress_, quality, TRUE); /* * The jpeg_mem_dest will reallocate if the required size is not @@ -208,18 +276,18 @@ int EncoderLibJpeg::encode(const std::vector> &src, * \todo Implement our own custom memory destination to prevent * reallocation and prefer failure with correct reporting. */ - jpeg_mem_dest(&compress_, &destination, &size); + jpeg_mem_dest(compress_, &destination, &size); - jpeg_start_compress(&compress_, TRUE); + jpeg_start_compress(compress_, TRUE); if (exifData.size()) /* Store Exif data in the JPEG_APP1 data block. */ - jpeg_write_marker(&compress_, JPEG_APP0 + 1, + jpeg_write_marker(compress_, JPEG_APP0 + 1, static_cast(exifData.data()), exifData.size()); - LOG(JPEG, Debug) << "JPEG Encode Starting:" << compress_.image_width - << "x" << compress_.image_height; + LOG(JPEG, Debug) << "JPEG Encode Starting:" << compress_->image_width + << "x" << compress_->image_height; ASSERT(src.size() == pixelFormatInfo_->numPlanes()); @@ -228,7 +296,7 @@ int EncoderLibJpeg::encode(const std::vector> &src, else compressRGB(src); - jpeg_finish_compress(&compress_); + jpeg_finish_compress(compress_); return size; } diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 1b3ac067..1ec2ba13 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,20 +28,40 @@ public: libcamera::Span destination, 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: + struct JpegData { + struct jpeg_compress_struct compress; + struct jpeg_error_mgr jerr; + }; + + int configureEncoder(struct jpeg_compress_struct *compress, + libcamera::PixelFormat pixelFormat, + libcamera::Size size); + int encode(const std::vector> &planes, libcamera::Span destination, libcamera::Span exifData, unsigned int quality); -private: void compressRGB(const std::vector> &planes); void compressNV(const std::vector> &planes); - struct jpeg_compress_struct compress_; - struct jpeg_error_mgr jerr_; + JpegData image_data_; + JpegData thumbnail_data_; + + // |&image_data_.compress| or |&thumbnail_data_.compress|. + struct jpeg_compress_struct *compress_; const libcamera::PixelFormatInfo *pixelFormatInfo_; bool nv_; bool nvSwap_; + + Thumbnailer thumbnailer_; }; diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 0cf56716..60eebb11 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,8 +115,9 @@ void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBu if (thumbnailSize != Size(0, 0)) { std::vector thumbnail; - generateThumbnail(source, thumbnailSize, quality, &thumbnail); - if (!thumbnail.empty()) + ret = encoder_->generateThumbnail(source, thumbnailSize, + quality, &thumbnail); + if (ret > 0 && !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 98309b01..55b23d7d 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -8,11 +8,11 @@ #pragma once #include "../post_processor.h" -#include "encoder_libjpeg.h" -#include "thumbnailer.h" #include +#include "encoder.h" + class CameraDevice; class PostProcessorJpeg : public PostProcessor @@ -25,14 +25,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 Thu Dec 1 09:27:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17927 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 43B4ABDE6B for ; Thu, 1 Dec 2022 09:27:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 021816333E; Thu, 1 Dec 2022 10:27:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886873; bh=iplbMEuMQO3zWgqhsm6dmOUFei8hsF9XV0txEyxKm8E=; 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=1r0F0SfeXzlPUW7oprwW2D0FiY+vTFYDidk2zfg/glZC5g3LwAJSjYOfQN7IdlzDG nnYd2lFtY0RniKV5D398dp03zPTR4Yjq85y8ZeCva3o8ed6g1GTeB2JqiWLmaO9s0b pL/k8uhFPjSGwWzGdHl1EbimWSR1pCxSOyGUVf+T5Eo3aYxGSEaZ7oNzdySCdo186P 0n2i0KoH3PXq2a+hapndNITFEi0l8G7xPTell95hgQ3/S8Lv3u/fG7g+ZGrhBccnQR +CHuydJ+Xj2IRuEt7lNXfDFrCcB8DnIyLHU9DpqVIqFvZ5g9pcJ4RfvfOkDk5YAeow B9AsFutwEha4w== Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D01A863336 for ; Thu, 1 Dec 2022 10:27:49 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="UILyxLEt"; dkim-atps=neutral Received: by mail-pf1-x42b.google.com with SMTP id z17so1344263pff.1 for ; Thu, 01 Dec 2022 01:27:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=q4mGcQFCHXSpFTQW/mKzrNKX6SYNHLglksp+4sXhYVo=; b=UILyxLEt32tAD48nkJxWe+UOKlFSe4xg4MoDxxgGvzmTJtMXey2qLRaHJIrCOuGhcR 5O5A/BiGvtYY36P8I7q5gmUQQTxAG5tGxoHViYw6AOCEE+VrUE4SAkbRZ7BYkBjyLOjk oBykJkHFHAwBJ5+DPlfk+0GNrfIrjPZJ5J6Oc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q4mGcQFCHXSpFTQW/mKzrNKX6SYNHLglksp+4sXhYVo=; b=RS+q/rK9k+yf9YoY5xAEBJ6iOUOHlyLWVAFVS5ukdQtWvwN1nuDq13qRVA2aQOgwQ1 HWLfkkpm7OX4xa8LDn9WXc4b1nlzh7Lb+WPALyu2xTp3bDMOfadWmGWOvAzx0wU1Iu/5 wI6S+0ob8ZK8ZpclA7RvEIj9IWApDcsyS2TT4UXZfuPdsG4Hd7IrNho1hSfMXSI0Wn01 AFkDAjtLvdrIygRTcVZOOoedYmbKwVckPd6KMG/LN2VXPnUe6ZXkd2ufXlWlaRCKP+br YhtnMVTLXFOHZa4btmBik81jQiL0VIfMn1XAZU6VcBN+4wPrreREtwhpDMT6n1w8l36r twWw== X-Gm-Message-State: ANoB5pleErEZuQkQ/tWhxU+n5NPRfw1WBDpESn7ew2lv/zeIjVAmj1hW LwvP87nVpjC6wytDcyIYT1gpyfl1ZR+aI4qQ X-Google-Smtp-Source: AA0mqf5NONTrG0ruo0fw6YErsI2CZZTJ3Zlmb2sw71XHgicFOewmPUySpavbkEkGFw0PNtzrtHtkOA== X-Received: by 2002:a05:6a00:408b:b0:56b:ca57:ba8c with SMTP id bw11-20020a056a00408b00b0056bca57ba8cmr47103000pfb.43.1669886867979; Thu, 01 Dec 2022 01:27:47 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:47 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:32 +0000 Message-Id: <20221201092733.2042078-6-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 5/6] 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang To prepare for the JEA encoder in the following patches, StreamBuffer is passed to Encoder::encoder, which contains the original FrameBuffer and Span |destination|. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart --- src/android/jpeg/encoder.h | 5 +++-- src/android/jpeg/encoder_libjpeg.cpp | 11 +++++++++++ src/android/jpeg/encoder_libjpeg.h | 7 +++++-- src/android/jpeg/post_processor_jpeg.cpp | 3 +-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index 7dc1ee27..eeff87b1 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 *streamBuffer, libcamera::Span exifData, unsigned int quality) = 0; virtual int generateThumbnail( diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index cc37fde3..d8d72fbd 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) @@ -192,6 +194,15 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) } } +int EncoderLibJpeg::encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer, + libcamera::Span exifData, + unsigned int quality) +{ + return encode(*streamBuffer->srcBuffer, + streamBuffer->dstBuffer.get()->plane(0), exifData, + quality); +} + int EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source, const libcamera::Size &targetSize, unsigned int quality, diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 1ec2ba13..6e9b65d4 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 *streamBuffer, libcamera::Span exifData, unsigned int quality) override; int generateThumbnail( @@ -44,6 +43,10 @@ private: libcamera::PixelFormat pixelFormat, libcamera::Size size); + int encode(const libcamera::FrameBuffer &source, + libcamera::Span destination, + libcamera::Span exifData, + unsigned int quality); int encode(const std::vector> &planes, libcamera::Span destination, libcamera::Span exifData, diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 60eebb11..10ac4666 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 Thu Dec 1 09:27:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 17928 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 AEF93C3284 for ; Thu, 1 Dec 2022 09:27:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6A02463336; Thu, 1 Dec 2022 10:27:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669886873; bh=KgBVeC479hx8nwxCUQfH81KCm4FAwzDWbVAlWZXCyUQ=; 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=rno4a/acshpgAqDtFJygLAu0GoLh/OBYL2p5kt3MJWzs0Dp/DkT6J9T2qqADsJzlT Y7rJL0tnBc/ZC3OkOTOCc+fn+Kl+GkVQgwjiNnqYiFE5UalxUVlzH1GpgRkViWaTQv 6AjfOgkp9WDF/xGYGjOhoEx1E7OnPd6tcg0VnTB66lnM4OG+Pd2PRgj4LnfhDjcPaa ctrodHW9MHF6MprRezyDmGdkH9pz6th+FrIoUZsUuSPGMtxw2UWAxOonwT442VGvTY Ov03dAW6txERT1gwbm0bBTRDJYyyvSS/vyDQ34ZMstqc9NYVZGCeul3k5zv5hc2oJr QoJOG827xIpCg== Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8F87D63336 for ; Thu, 1 Dec 2022 10:27:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="OT6OmqcR"; dkim-atps=neutral Received: by mail-pj1-x1032.google.com with SMTP id cm20so1330499pjb.1 for ; Thu, 01 Dec 2022 01:27:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=p0n4GYoGdVuD6ag/A8hLDe9e8xGF6rYG6bYzbxH7S6A=; b=OT6OmqcRZiMMvWnglyrhgg1BXr5ah0ouacwN5hwNRMvzTY6bLL8BNP2vv4RMkGGCkW yX1TCLMGWnU49deroqFn432g/r0MFnqu1CLxBI3bb+QIEuY9ALbe4YrFdmwCFfLU7PpV 8fNsB5M1aTeyhyoagO/TIHXoLmXwcML+DHsh4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=p0n4GYoGdVuD6ag/A8hLDe9e8xGF6rYG6bYzbxH7S6A=; b=WpPQbmuE+k0cIPWTY5ZUD4Rwnrm37xLi7q5d1U1DIf+YLZhl3z/GBqJ4k9cpCnhYYz +VsY3gMiExOwvQS2YvtUYCMwZw8c2bTXvWy4uixYETfuHqZhUBIABpwHRRG7lOPb7AXY Kxgs4d67LyUK9/rrqRiV+PGJhZKS1QLetUhdKyoqiQx44EdTLnyE72drTr2wpTrUZt9c CKIrGediFRYnOELOFgxrxFASwHpjulcJ05qj4hq2G+539MGMFOlxFeRkZn5netzWEqCC Q1fE6Z7zgh4rZYzHK3kl8eq3KeQo4P8lJjJxGlJV4XSPYEqWtPRFuF9d6Mhkn4LrB2iM OV6Q== X-Gm-Message-State: ANoB5pkI0ntMtRQL8kRCD5CqbJq+zKsvKjmOODI6uYl3fLMccC26nDfj IJMNSGzbk/NlLxktkFpyfxugEnH8MsaVBlUK X-Google-Smtp-Source: AA0mqf4+L6fQZKcllU5mA0Jy3gl4jtCd7MbtQ3v9ubLNtkbrXDS14Q17mLq1WYPibwU9AyBJrvcxhQ== X-Received: by 2002:a17:902:7c82:b0:189:760d:c5f2 with SMTP id y2-20020a1709027c8200b00189760dc5f2mr26980885pll.90.1669886869481; Thu, 01 Dec 2022 01:27:49 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id z9-20020a1709027e8900b00186b8752a78sm3108050pla.80.2022.12.01.01.27.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Dec 2022 01:27:49 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Dec 2022 09:27:33 +0000 Message-Id: <20221201092733.2042078-7-chenghaoyang@google.com> X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog In-Reply-To: <20221201092733.2042078-1-chenghaoyang@google.com> References: <20221201092733.2042078-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 6/6] 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: Harvey Yang via libcamera-devel From: Harvey Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang This patch adds JEA implementation to replace Lib Jpeg in cros platform, where HW accelerator is available. Signed-off-by: Harvey Yang Reviewed-by: Laurent Pinchart --- src/android/cros/camera3_hal.cpp | 2 + src/android/cros_mojo_token.h | 12 +++ src/android/jpeg/encoder_jea.cpp | 93 ++++++++++++++++++++++++ src/android/jpeg/encoder_jea.h | 35 +++++++++ src/android/jpeg/meson.build | 12 ++- src/android/jpeg/post_processor_jpeg.cpp | 8 ++ 6 files changed, 160 insertions(+), 2 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 fb863b5f..d75afccb 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) { + 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 00000000..043c752a --- /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 00000000..66a854c4 --- /dev/null +++ b/src/android/jpeg/encoder_jea.cpp @@ -0,0 +1,93 @@ +/* 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 -ENOTSUP; + + libcamera::MappedFrameBuffer frame(&source, + libcamera::MappedFrameBuffer::MapFlag::Read); + + if (frame.planes().empty()) + return -ENODATA; + + 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. + const int kApp1MaxDataSize = 65532; + thumbnail->resize(kApp1MaxDataSize); + + if (!jpegCompressor_->GenerateThumbnail(frame.planes()[0].data(), + size_.width, size_.height, + targetSize.width, + targetSize.height, quality, + thumbnail->size(), + thumbnail->data(), + &outDataSize)) { + thumbnail->clear(); + return -EBUSY; + } + + thumbnail->resize(outDataSize); + return outDataSize; +} diff --git a/src/android/jpeg/encoder_jea.h b/src/android/jpeg/encoder_jea.h new file mode 100644 index 00000000..2eba31c2 --- /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 08397a87..d25016b1 100644 --- a/src/android/jpeg/meson.build +++ b/src/android/jpeg/meson.build @@ -1,8 +1,16 @@ # 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 10ac4666..15115424 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); }