From patchwork Fri Aug 23 14:29:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 21003 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 348DDBDE17 for ; Fri, 23 Aug 2024 14:32:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ABCFF633CF; Fri, 23 Aug 2024 16:32:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="mDObCun8"; dkim-atps=neutral Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D49F6633CB for ; Fri, 23 Aug 2024 16:32:09 +0200 (CEST) Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-3719896b7c8so995207f8f.3 for ; Fri, 23 Aug 2024 07:32:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1724423529; x=1725028329; darn=lists.libcamera.org; 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=IDX86hfigYN0gC08TEOpl2L7+W79GzBQ1t4h96ImMug=; b=mDObCun8ewi3ZySg2kNfGt/Z/AelQwouR11+MNZQZlSYZnuiS4Ua4JjsnF6Q9NFtwv z3TfO9hLSzkSFAwmSYZJAvlHwUMrAtiTl8MYBcMIBiBMNF7NQMoaYHecP8sHRvr+EyCC xP9WYUKElzZvui6LAKlVE+j5m05KA/OHTw6xE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724423529; x=1725028329; 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=IDX86hfigYN0gC08TEOpl2L7+W79GzBQ1t4h96ImMug=; b=cagwVKYg7ZnCPb6j3N2+J2O7IKPgsuGnJAHVDcU9B4mGCTKM/ZoYPUk/HenDUoQzjk AceHwmVs/d4u1gwJY/fiZa+3pNPtnDLlg920LE/HMqBkHHD3wX6cN6EYG8CEpaIp+934 aXgoq9uhZNoSVCdxcjig2BqTuNr4azC+ZDipU4l6cw9lQXtc4QajNz58aPSxSKoSrTdr sUOGj8IY3LDCKyLAcfFgpQgFAYnaiV1rvtmmJmyfo+o2pZWLKpsWVPzQ9tVQuXieLiv6 2N13gIMuKcd807kMFSZXBudjuXqncIyZhVWtgizCNUlVPXoBLGvijsF0vmzNYe0JU5cD RMTA== X-Gm-Message-State: AOJu0YyJB1sfKd9/7x5TK0RAQBYrgOB7q223IWSfuH9yrVw/1LnNMfmb rZzDAfw9WZX89P7qv0eJ4O2aeWAfQbJlvzRaIeWDxz4JbnkhTFBKnShuhts6OovhUxTcx3diUEx aFA== X-Google-Smtp-Source: AGHT+IEsAu7rW+IxEVWVzL8BSpS0ALyOQzM6I1UwWj7bVrdTsy9JlEml6sCQmYLfI5w5tL16S9h6JA== X-Received: by 2002:a05:6000:e4f:b0:36d:2984:ef74 with SMTP id ffacd0b85a97d-37311863b12mr1598145f8f.35.1724423528844; Fri, 23 Aug 2024 07:32:08 -0700 (PDT) Received: from chenghaoyang-germany.c.googlers.com.com (161.126.77.34.bc.googleusercontent.com. [34.77.126.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-373081ffb66sm4300627f8f.84.2024.08.23.07.32.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Aug 2024 07:32:08 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , Harvey Yang Subject: [PATCH v2 1/3] libcamera: Add rectangle two-point constructor Date: Fri, 23 Aug 2024 14:29:08 +0000 Message-ID: <20240823143205.2668765-2-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.295.g3b9ea8a38a-goog In-Reply-To: <20240823143205.2668765-1-chenghaoyang@google.com> References: <20240823143205.2668765-1-chenghaoyang@google.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Yudhistira Erlandinata Add a Rectangle constructor that accepts two points: topLeft and bottomRight. BUG=b:308714092 TEST=emerge-geralt libcamera-mtkisp7 Signed-off-by: Yudhistira Erlandinata Co-developed-by: Harvey Yang --- include/libcamera/geometry.h | 10 ++++++++++ src/libcamera/geometry.cpp | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 3e6f0f5d7..978322a22 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -8,7 +8,9 @@ #pragma once #include +#include #include +#include #include #include @@ -262,6 +264,14 @@ public: { } + constexpr Rectangle(const Point &topLeft, const Point &bottomRight) + : x(topLeft.x), y(topLeft.y), + width(bottomRight.x - x), + height(bottomRight.y - y) + { + assert(bottomRight.x >= x && bottomRight.y >= y); + } + int x; int y; unsigned int width; diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 000151364..86385ad35 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -5,13 +5,13 @@ * Geometry-related structures */ -#include - #include #include #include +#include + /** * \file geometry.h * \brief Data structures related to geometric objects @@ -629,6 +629,13 @@ std::ostream &operator<<(std::ostream &out, const SizeRange &sr) * \param[in] size The desired Rectangle size */ +/** + * \fn Rectangle::Rectangle(const Point &topLeft, const Point &bottomRight) + * \brief Construct a Rectangle with the two given points + * \param[in] topLeft The top-left corner + * \param[in] bottomRight The bottom-right corner + */ + /** * \var Rectangle::x * \brief The horizontal coordinate of the rectangle's top-left corner From patchwork Fri Aug 23 14:29:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 21004 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 1EA53C32C2 for ; Fri, 23 Aug 2024 14:32:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BBBBB633D2; Fri, 23 Aug 2024 16:32:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Q2yI6sH+"; dkim-atps=neutral Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A7637633CE for ; Fri, 23 Aug 2024 16:32:10 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-3719f0758c6so1109977f8f.1 for ; Fri, 23 Aug 2024 07:32:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1724423529; x=1725028329; darn=lists.libcamera.org; 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=djAA4idgeV6EJbCGqlIZlZ4tuy/a4YT0To9eKJrnat8=; b=Q2yI6sH+JumOVUQYF3Y2p/nKzMQ7urCFUGVzz20VXtBx6NI5KpRVx0TfIcjWVBHXkY KkOLFE/Pi3OouoayJxM7p1bMzw++uxSVsH6jy/AfbWq0WJZLs6DELQXsNEUI1nd4EgjH JTXJUnuuCYv4yO64Uul2sdfPztweV17fP7gfo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724423529; x=1725028329; 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=djAA4idgeV6EJbCGqlIZlZ4tuy/a4YT0To9eKJrnat8=; b=vJhy4BCClHyGhyIGkBafPVCcfYWdpI4FYRqeZzN3QpEaSxAO4OmJ9LoaqcK3mWvn/f aqcAxgpKRN4qx6VONkcrtC8OHpoQxrERc6QYmlrV4T9vSnI098342O1ciAN6u3Rumykv px2vmBIBGRu8n7Ku4VW65sn/lOGWAMbaWia3Cr1jJ4yKB62BX9wK3Ua87QXKQSI8PEZc e4ySU61CHp6gqcntKNecpTYEQ6CLyNJOn0qLaQ3/sPq7DlNQeENg0iRNmlfD38Gtrmwl oZ14ZYGo9zDYjg0fD+QP6m04uOfFMhLxFZd00NDLKd1pAUkHOAGE2cmdXHBEm8xcEFL0 Q5Uw== X-Gm-Message-State: AOJu0Yzvh2aO4BkoIvSRd/XN8CWZXygwj8wQf81Cb4ypDP/MojiWvbuA imrGvAA/aoDpoOEg+Yx0Pkdg9Wx+5UwsQGomlDhNkF1FYjPXV4t5g2DxHoLe9vzTtMqWEMujE0h u7A== X-Google-Smtp-Source: AGHT+IH0Kzux6SAppsLHkh3CJnaHaYA7HESc7qSDz3T+wXFEbEAgCM12k/Fdse6g4uvpG/n/cb7u3w== X-Received: by 2002:a5d:56d0:0:b0:367:909b:8281 with SMTP id ffacd0b85a97d-373118e9e82mr1519388f8f.59.1724423529293; Fri, 23 Aug 2024 07:32:09 -0700 (PDT) Received: from chenghaoyang-germany.c.googlers.com.com (161.126.77.34.bc.googleusercontent.com. [34.77.126.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-373081ffb66sm4300627f8f.84.2024.08.23.07.32.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Aug 2024 07:32:09 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , becker hsieh , Harvey Yang Subject: [PATCH v2 2/3] libcamera: Add face detection controls Date: Fri, 23 Aug 2024 14:29:09 +0000 Message-ID: <20240823143205.2668765-3-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.295.g3b9ea8a38a-goog In-Reply-To: <20240823143205.2668765-1-chenghaoyang@google.com> References: <20240823143205.2668765-1-chenghaoyang@google.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Yudhistira Erlandinata Add FaceDetectMode, FaceDetectFaceRectangles, FaceDetectFaceScores, and FaceDetectFaceLandmark. Also add ControlTypePoint for supporting FaceDetectFaceLandmark. BUG=b:308713855 TEST=emerge-geralt libcamera-mtkisp7 Signed-off-by: Yudhistira Erlandinata Co-developed-by: becker hsieh Co-developed-by: Harvey Yang --- include/libcamera/controls.h | 6 +++++ src/libcamera/control_ids_core.yaml | 42 +++++++++++++++++++++++++++++ src/libcamera/controls.cpp | 6 +++++ 3 files changed, 54 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 7c2bb2872..bf1b8609c 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -34,6 +34,7 @@ enum ControlType { ControlTypeString, ControlTypeRectangle, ControlTypeSize, + ControlTypePoint, }; namespace details { @@ -87,6 +88,11 @@ struct control_type { static constexpr ControlType value = ControlTypeSize; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypePoint; +}; + template struct control_type> : public control_type> { }; diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index 6381970b4..5ff46c71e 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -860,6 +860,48 @@ controls: No further state changes or lens movements will occur until the AfPauseResume control is sent. + - FaceDetectMode: + type: uint8_t + description: | + Reporting mode of face detection. + + enum: + - name: FaceDetectModeOff + value: 0 + description: | + Pipeline should not report face detection result. + - name: FaceDetectModeSimple + value: 1 + description: | + Pipeline should at least report faces boundary rectangles and + confidence score for each of them. + + - FaceDetectFaceRectangles: + type: Rectangle + description: | + Boundary rectangle of the detected faces. + + size: [n] + + - FaceDetectFaceScores: + type: uint8_t + description: | + Confidence score of each of the detected faces by face detector. + The range of score is [0, 100], but usually those with low confidence + scores will not be included. + Currently identical to ANDROID_STATISTICS_FACE_SCORES. + + size: [n] + + - FaceDetectFaceLandmark: + type: Point + description: | + Array of human face landmark coordinates in format: + [..., left_eye_i, right_eye_i, mouth_i, left_eye_i+1, ...], + with i = index of face. + + size: [n] + - HdrMode: type: int32_t description: | diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 11d35321c..ce73ae9d7 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -61,6 +61,7 @@ static constexpr size_t ControlValueSize[] = { [ControlTypeString] = sizeof(char), [ControlTypeRectangle] = sizeof(Rectangle), [ControlTypeSize] = sizeof(Size), + [ControlTypePoint] = sizeof(Point), }; } /* namespace */ @@ -255,6 +256,11 @@ std::string ControlValue::toString() const str += value->toString(); break; } + case ControlTypePoint: { + const Point *value = reinterpret_cast(data); + str += value->toString(); + break; + } case ControlTypeNone: case ControlTypeString: break; From patchwork Fri Aug 23 14:29:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harvey Yang X-Patchwork-Id: 21005 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 64BA8BDE17 for ; Fri, 23 Aug 2024 14:32:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 78CD5633D7; Fri, 23 Aug 2024 16:32:18 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="dBv1GOI7"; dkim-atps=neutral Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DB11E633CF for ; Fri, 23 Aug 2024 16:32:10 +0200 (CEST) Received: by mail-wr1-x42e.google.com with SMTP id ffacd0b85a97d-3719f0758c6so1109981f8f.1 for ; Fri, 23 Aug 2024 07:32:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1724423530; x=1725028330; darn=lists.libcamera.org; 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=aH7hiKimyPigrNoK5TEoeqT1W2nUv57fQS07j7w7vd0=; b=dBv1GOI7/gRggAFYI+0y5ieA4aTnfRwCdvib+XzSba0he2eMtzNDX0P/DxShqndDO4 NTf2o3pxHqZMD99v0wVGywhAVCV18MacxE08XYUibd+HCC4/CLzG+Ni2r7LTzTndGaRb 5tzFk1cs/F83myTlv5BNW+CfvA1bqS+I4TibU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724423530; x=1725028330; 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=aH7hiKimyPigrNoK5TEoeqT1W2nUv57fQS07j7w7vd0=; b=JJrM64XFzfE3HkAcMNbstI5EHOo/7kJn7w3SY73XuS96MmuLXffZl/8T1i6yaeRS5q VOnlU4SofcMSvXB0yUXRLmP560rwpiIpFFhfqNxQMaY6baXf6v9M1oC+RYe2MG2mrrpe yromd26ELDDClFuqo1YuM/gdEcvhIo8z9+3nLqyqyrBVXQUtw7KvD2YAmN+rzDbuZQ/S lNfMKilZBsV+qXY9Q+1TBfZSj0CBAUL36fBXv9DQi/bO21uN5Hb+sQ8u/XgdwXox42pN 9m8Yd1bkKBw/H4lihVcefDnvT3dipm2bXX3nKUXQ5jnMR22GAAkRhDC1PMtOg7y3B0o6 Rjgg== X-Gm-Message-State: AOJu0Yx/4ye4ps0On8MswUDbR95celMfT2xeyuicalD420bZKE5yD44V xt/hMDhoTH7vaMAlLa2LlT7yXmNuMZpSfOGJFfgXYh4wXgJvtO2mciHDrHrAwUfoRkaQYWD0Br0 6Rg== X-Google-Smtp-Source: AGHT+IFqeKDVYybOSYwXSsdkvthCF9O0KgiFc06MqAkSozNwUAv5doLD9IxhVyPxR7a1/Q6RY+h1vA== X-Received: by 2002:adf:b19c:0:b0:368:37e3:dff7 with SMTP id ffacd0b85a97d-37311863b94mr1701776f8f.34.1724423530095; Fri, 23 Aug 2024 07:32:10 -0700 (PDT) Received: from chenghaoyang-germany.c.googlers.com.com (161.126.77.34.bc.googleusercontent.com. [34.77.126.161]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-373081ffb66sm4300627f8f.84.2024.08.23.07.32.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Aug 2024 07:32:09 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , Harvey Yang Subject: [PATCH v2 3/3] libcamera: android: Add face detection control support Date: Fri, 23 Aug 2024 14:29:10 +0000 Message-ID: <20240823143205.2668765-4-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.295.g3b9ea8a38a-goog In-Reply-To: <20240823143205.2668765-1-chenghaoyang@google.com> References: <20240823143205.2668765-1-chenghaoyang@google.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Yudhistira Erlandinata Allow Android HAL adapter to pass the face detection metadata control to the pipeline and also send face detection metadata to the camera client if the pipeline generates it. Squashed CL: https://chromium-review.googlesource.com/c/chromiumos/third_party/libcamera/+/5065292 Don't use ControlInfoMap::count() and ControlInfoMap::at() because its internal assumption is wrong: The ControlIdMap and its idmap have a 1:1 mapping between their entries. BUG=b:308713855 TEST=emerge-geralt libcamera-mtkisp7 Signed-off-by: Yudhistira Erlandinata Co-developed-by: Harvey Yang --- src/android/camera_capabilities.cpp | 41 ++++++++++++++++-- src/android/camera_device.cpp | 64 +++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp index 71043e127..31d113d51 100644 --- a/src/android/camera_capabilities.cpp +++ b/src/android/camera_capabilities.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -1176,11 +1177,43 @@ int CameraCapabilities::initializeStaticMetadata() maxFrameDuration_); /* Statistics static metadata. */ - uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, - faceDetectMode); - int32_t maxFaceCount = 0; + auto iter = camera_->controls().find(controls::FaceDetectMode.id()); + if (iter != camera_->controls().end()) { + const ControlInfo &faceDetectCtrlInfo = iter->second; + std::vector faceDetectModes; + bool hasFaceDetection = false; + for (const auto &value : faceDetectCtrlInfo.values()) { + auto mode = value.get(); + uint8_t androidMode = 0; + switch (mode) { + case controls::FaceDetectModeOff: + androidMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + break; + case controls::FaceDetectModeSimple: + androidMode = ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE; + hasFaceDetection = true; + break; + default: + LOG(HAL, Fatal) << "Received invalid face detect mode: " + << static_cast(mode); + } + faceDetectModes.push_back(androidMode); + } + if (hasFaceDetection) { + // todo(yerlandinata): Create new libcamera controls + // to query max possible faces detected. + maxFaceCount = 10; + staticMetadata_->addEntry( + ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, + faceDetectModes.data(), faceDetectModes.size()); + } + } else { + uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, + faceDetectMode); + } + staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, maxFaceCount); diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 493f66e7b..cd600eade 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -9,12 +9,12 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "system/graphics.h" @@ -813,6 +814,14 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor) controls.set(controls::ScalerCrop, cropRegion); } + if (settings.getEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, &entry)) { + const uint8_t *data = entry.data.u8; + controls.set(controls::FaceDetectMode, data[0]); + if (!controls.get(controls::FaceDetectMode)) { + LOG(HAL, Warning) << "Pipeline doesn't support controls::FaceDetectMode"; + } + } + if (settings.getEntry(ANDROID_SENSOR_TEST_PATTERN_MODE, &entry)) { const int32_t data = *entry.data.i32; int32_t testPatternMode = controls::draft::TestPatternModeOff; @@ -1540,8 +1549,9 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE, value32); - value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, value); + settings.getEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, &entry); + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, + entry.data.u8, 1); value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, @@ -1580,6 +1590,54 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_SENSOR_FRAME_DURATION, *frameDuration * 1000); + const auto &faceDetectRectangles = + metadata.get(controls::FaceDetectFaceRectangles); + if (faceDetectRectangles) { + const Span rectangles = *faceDetectRectangles; + std::vector flatRectangles; + for (const Rectangle &rect : rectangles) { + flatRectangles.push_back(rect.x); + flatRectangles.push_back(rect.y); + flatRectangles.push_back(rect.x + rect.width); + flatRectangles.push_back(rect.y + rect.height); + } + resultMetadata->addEntry( + ANDROID_STATISTICS_FACE_RECTANGLES, flatRectangles); + } + + const auto &faceDetectFaceScores = + metadata.get(controls::FaceDetectFaceScores); + if (faceDetectRectangles && faceDetectFaceScores) { + const Span &scores = *faceDetectFaceScores; + if (scores.size() != faceDetectRectangles->size()) { + LOG(HAL, Error) << "Pipeline returned wrong number of face scores; " + << "Expected: " + << faceDetectRectangles->size() + << ", got:" << scores.size(); + } + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_SCORES, scores); + } + + const auto &faceDetectFaceLandmarks = + metadata.get(controls::FaceDetectFaceLandmark); + if (faceDetectFaceScores && faceDetectRectangles && + faceDetectFaceLandmarks) { + const auto &landmarks = *faceDetectFaceLandmarks; + size_t expectedLandmarks = faceDetectRectangles->size() * 3; + std::vector androidLandmarks; + for (const auto &landmark : landmarks) { + androidLandmarks.push_back(landmark.x); + androidLandmarks.push_back(landmark.y); + } + resultMetadata->addEntry( + ANDROID_STATISTICS_FACE_LANDMARKS, androidLandmarks); + if (landmarks.size() != expectedLandmarks) { + LOG(HAL, Error) << "Pipeline returned wrong number of face landmarks; " + << "Expected: " << expectedLandmarks + << ", got: " << landmarks.size(); + } + } + const auto &scalerCrop = metadata.get(controls::ScalerCrop); if (scalerCrop) { const Rectangle &crop = *scalerCrop;