From patchwork Fri Sep 25 08:51:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9822 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 7AC63C3B5E for ; Fri, 25 Sep 2020 08:51:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 141FF6303A; Fri, 25 Sep 2020 10:51:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="cBGGR0Ln"; dkim-atps=neutral Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3BAB160576 for ; Fri, 25 Sep 2020 10:51:33 +0200 (CEST) Received: by mail-wr1-x442.google.com with SMTP id g4so2680371wrs.5 for ; Fri, 25 Sep 2020 01:51:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XUoWlq3axycFFStrgLqMBP3hphWhqff4qmdHXOg0LAY=; b=cBGGR0Ln2xGrO4mXYRfLiFj1BKPZZtraAcP0s+xUsqa58an/CD+DkNgFzEvKjZfgo/ zXFJwy0Zg32V6ydFvzAP2qii7AVV8HkqB7sEhlh5MtGsC0ceovtoBAalpnoW18kiHyuH EpNywJPkOBvZZ6+sCx/3d+hwwpX1p+lJGbef7D0O1zxBRXG8ZGsqYkifkRmax1eMuD5h nw4WmGEXWBDBXXO6uDkXNSbXA7RaBUnuMSyyzC9NVuNxsmE4Oxcx1Mym9ML3sEb0FPTB 0k5bvQFVgXxcDoJ3EY3638g10KcPWpZgvF+H7HqQIS8DOdp1/q02Zy8GNOb9cBHP8DCP IsBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XUoWlq3axycFFStrgLqMBP3hphWhqff4qmdHXOg0LAY=; b=JB0exunvIuKZqTzp/ynAOmsEQIOx1Gn1gbXlMBYN9oR23gnldCLKnbsgB/1oj2hZeM au9dux2lkh4NdmM2IsVEaJY/pUDqPjUp6mW2OC4nv802gu+1ccVbWKMprGOF38XQp3hw wN125CySgFxgy6lmWZmNWwinL0725pJKFZXuVUYeAcOojyYwcmG7K6wwMS6l/dNE6oT4 nAIudAMAnq9b43qoJFWZ9KNvHZ/sA9sMAqCjEQSS5p0kXcZTfJ36c9iy8lpbG3yZozNo UeV81Q0QpDfY6wVkPmlSxbQ6DSAp4xH48Qvm3oIC+4gNdf41T1DnYLBkftuS75JNUMlh q+mA== X-Gm-Message-State: AOAM533KQWGDRefO68iqbmUdbtGzczT9R0X+ZLhTgw7uUtqgssdSUyB4 SDXEiJNuOdHImIb5KIwE8c6BQnsKy8KKYw== X-Google-Smtp-Source: ABdhPJxwMOuoxFDMbkvOBSViCsejL6m+sisBkG43F08yf+RAEM/zk7XxPOa5ahAj6D9DOeISpBOk8A== X-Received: by 2002:adf:ec47:: with SMTP id w7mr3511178wrn.175.1601023892692; Fri, 25 Sep 2020 01:51:32 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:32 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:22 +0100 Message-Id: <20200925085127.17214-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/6] libcamera: Add SensorOutputSize property 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" The SensorOutputSize camera property reports the image size that the next step in processing after the sensor and CSI-2 receiver - usually the ISP - will see. It will normally change when a new camera mode is selected, and can be used to implement digital zoom. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- src/libcamera/property_ids.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index 74ad019..8011b88 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -640,4 +640,23 @@ controls: \todo Rename this property to ActiveAreas once we will have property categories (i.e. Properties::PixelArray::ActiveAreas) + - SensorOutputSize: + type: Size + description: | + The size, in pixels, of the image being used to produce the + desired output streams. The image size might correspond to the + size of the frames produced by the image sensor but would also + take into account additional cropping (or even re-scaling) + performed by the CSI-2 receiver to adjust the sensor frame + size to conform to the output image sizes and aspect ratios. + The property is meaningful only after the Camera has been + successfully configured and its value changes whenever a new + configuration is applied. It can be used to implement digital + zoom. + + \sa controls::ISPCrop + + \todo Move this property to CameraConfiguration once the + feature is made available + ... From patchwork Fri Sep 25 08:51:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9823 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 0512EC3B5C for ; Fri, 25 Sep 2020 08:51:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C993B6303F; Fri, 25 Sep 2020 10:51:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="c3d1EgOG"; dkim-atps=neutral Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0F2B863038 for ; Fri, 25 Sep 2020 10:51:34 +0200 (CEST) Received: by mail-wm1-x343.google.com with SMTP id a9so2387488wmm.2 for ; Fri, 25 Sep 2020 01:51:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZganqNCKgpZBIWeH0OLpzeE1oHtR5CBwAEI3tRbcGyI=; b=c3d1EgOGrAssRQ9cWsk0sB3PB54+Md/yxC/IT2hEidYoUFZauqocztnxVhujfSqN7w TNesz9WLnjjscc9b2iHCLvIMDnEoIK0CPUg+vfoUJsIBVzrx3mBURO3wJ3xaFePgf6T/ +4ZfLmSCzTh61XO3u81NOOeH8WlVT8LUAi7pM7LdIAZsSwNRvWBl65iZC2x84uYA/uYk mZBq9Ky+fFDR1sq+BxX4sxuYB1xb2U5UbVwpsqIuZ/BqLaWujkgX08G71rtCb1Q2VEqX GMHaBEnpLlEDQJNYgQVm/zmf/M2oCTHUrejIoP+yW9lNRy/IuWvGotTcLHn5kNFbluaI Gd3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZganqNCKgpZBIWeH0OLpzeE1oHtR5CBwAEI3tRbcGyI=; b=sSJ2yh25CVrkbPZUFn0PXEneyx5IaMl0aXAHvcqtlZ/tRrYXgCDMCN970QuzrxWP2U zuDtpg5/BbdFlxI1Br7QPlGMByYuF4W7ugyyAZkEGVNT7goTihfIeCu7MisSx9ee/UJy rTU6L1W5XQmKM6hKWtIAMio1x0jmgkrFS2u6ADUeAUE4g2aDmdfP7D4lpJLYnnVGAnfW kNKlLwVjxLpaUFBDjEQacbBhCB7QM5rKfhwcNIQlJxMyH/xIDh03PwA6jh6a9afJgAD6 Z5uyZPWdcYfNcIoavyLAgV1pd80GKicJAZH9xaCzIBTAmpsxAugtHr71bN3kJN1CmTT1 2CuA== X-Gm-Message-State: AOAM533bDChhx947o3zwL9YXMDixf5VVtquGLvdhXes/4gbQBOLBaYsp BBseNV91G/qgQWp5ZllmQzmRumYP7zkILw== X-Google-Smtp-Source: ABdhPJwzss4To/uK9Tnd5RYAtLCR28Yblb5QgnalDdM/zco6TSKkVb6Htuhdp2+OTo5ZRShETXs1iQ== X-Received: by 2002:a05:600c:21cd:: with SMTP id x13mr1936797wmj.63.1601023893519; Fri, 25 Sep 2020 01:51:33 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:32 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:23 +0100 Message-Id: <20200925085127.17214-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/6] libcamera: Initialise the SensorOutputSize property 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" Add a default initialisation according to the sensor resolution, though it will need updating when the camera mode changes. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index d2679a4..c9a19b0 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -277,6 +277,12 @@ int CameraSensor::init() */ resolution_ = sizes_.back(); + /* + * Set a default value for the SensorOutputSize, though it will have to + * be updated when new camera modes are chosen. + */ + properties_.set(properties::SensorOutputSize, resolution_); + return 0; } From patchwork Fri Sep 25 08:51:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9824 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 8A880C3B5C for ; Fri, 25 Sep 2020 08:51:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3BD3763042; Fri, 25 Sep 2020 10:51:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="svm42jGy"; dkim-atps=neutral Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D06FF62FD8 for ; Fri, 25 Sep 2020 10:51:34 +0200 (CEST) Received: by mail-wr1-x444.google.com with SMTP id a17so2676494wrn.6 for ; Fri, 25 Sep 2020 01:51:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AXKbuxsOAsGCCzcgdzcbXq7E8buv4RVCzCrQy06ZqSo=; b=svm42jGyCrEQqoaNR1wsXJJzbHk/wu5O6N/7mwZ3u9eEz4fvZytdBxw4Ka7siuvGQo qv+oso0FLSMlFOS8hov09ftdUM62nsB0s8ZLr4HAT6ie8IC8gltUdRHz2XLto83fEUk/ EgizASVtMf/vdKMGIgU1djDmiozAnD4dEFIqMdKvmCl91zBpxD2FpaNfQ3YODTOvqQ7E 8M+A889qIEs6MhBGYdUrxcG7Q8Wi6CZUdpsoYWzwdfAFUJh/mNf/BCoJ1FZ2Brs6WE9R GsttzpZsLf1tIVAUKo7DOM7sQCFmg268g2IP3kkJKxccR7XW7ekTQRPewaWRFsED92KR dBLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AXKbuxsOAsGCCzcgdzcbXq7E8buv4RVCzCrQy06ZqSo=; b=XI4P3ReWviSmnGLP+9ld5wMpRjPcwERAJ1DzhMo09elGB7bb4hRZl24k8yqItoCISZ IIWqrkIdPwQy3nRP+PetEQE5ScPWEXJ8XrA19NWkoXff8Q6I5/f+F6o3TcUcq3ni/tsh b3eu7cAU+/vKW21nUM01Z4WBAsp85JywU0izqF7afpyOTDUUtDB1vokG/DBDT0PDOosb VebkQ2yrLLPaKvO7rRVmd7i8K1Tys2DBVy1tYnJJibsnVYvrJGbBp+DABZn/7HiYOmBR 93UIc2aDMv1HsGmYy/rnCjF/wU00ZQPoEN11EnNNc+mSbukeL6iO2+zt1QTs3q+Mcy38 BF0Q== X-Gm-Message-State: AOAM531tm3n4uMEm9kSHu4psaR2VQxSmjzQfvsNC3sTFt0hFOMR5PmVl t8mQaNhZXHcp14H0xYrWqsV3vqcKfhQeBA== X-Google-Smtp-Source: ABdhPJwTHugPt2j749zxnx7KZwN6BjTQ25ZG3GhCfAXKlF6MeNwW/mz2/psfL5L+OcWGfq7CX5iQhQ== X-Received: by 2002:adf:f190:: with SMTP id h16mr3336325wro.202.1601023894347; Fri, 25 Sep 2020 01:51:34 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:33 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:24 +0100 Message-Id: <20200925085127.17214-4-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/6] libcamera: Add IspCrop control 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" The IspCrop control selects how much of the sensor's output image will be scaled to form the output image. It can be used to implement digital zoom. Signed-off-by: David Plowman --- src/libcamera/control_ids.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml index 3560d4a..a6a73c8 100644 --- a/src/libcamera/control_ids.yaml +++ b/src/libcamera/control_ids.yaml @@ -273,4 +273,13 @@ controls: order in an array of 9 floating point values. size: [3x3] + + - IspCrop: + type: Rectangle + description: | + Sets the portion of the full sensor image, in pixels, that will be + scaled up to form the whole of the final output image. This control + can be used to implement digital zoom. The size of the full sensor + image within which an application can crop is available from the + SensorOutputSize property. ... From patchwork Fri Sep 25 08:51:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9825 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 55298C3B5C for ; Fri, 25 Sep 2020 08:51:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0713362FD8; Fri, 25 Sep 2020 10:51:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="pR7lKQXk"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C985862FD8 for ; Fri, 25 Sep 2020 10:51:35 +0200 (CEST) Received: by mail-wm1-x334.google.com with SMTP id e11so1394270wme.0 for ; Fri, 25 Sep 2020 01:51:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Y6wMl7PkxTQWHlM083BAuuViyy3KDW3mwMnkJU5FjHI=; b=pR7lKQXkmrpnjt5hG8XmndvMwo6j4jKz6DfI9JQwEcQGYF3seTB+0odR8r0wxp2VhQ wMKk3/1wbH3ly8i6ZLRC6FwGmDK6SQuKlAU7hF+c466C4ds8RjOVHzRfS4u63l/ilohf hyXiCdLmZZjARuGSns/QvNVFC9SFIbiBngZO/1PZjWpSX/hWTkr4WTuRSZv/8fARIGRL tAsdjpoTBlhviZixMN79aGEB6d1zEH0JTkwGbmqzeWSGaNcyaLiLeFPIk+YVck9MaDQp p4C76uzjESp9IpAmdd1Li1a1zUEgfGT9BylsqSPSPP7Vg9d77EvTqKHyVaMDXUo4tejt c1NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Y6wMl7PkxTQWHlM083BAuuViyy3KDW3mwMnkJU5FjHI=; b=Bhxy87jPKalnr5p15SSYLHVsGrYLMLgeeuC4wlPP8LLtlyYO6fXd1q5HMRBoMoxQbd 99SNwLkOf/1eLc5mtKVYpaw5XakpZcr9bPU6nf9ayZizFxZHYw8eVWB6l1Y9kk/RhzWc rWmlHbfewVKrdVbxQEokutTyB+nBZno+9DyTRSedFb+juPsg+uX0x4sk5MZvrj/qwFZ2 Mjb2zKqqJlMFrgX9/aPI17ZzShb1HkgjzqohM/EfybXv2mYwhnYaTg4AUtrTAp9H68lM DpbFhvqQVYsrHCtNvkP4i/Iu/2xc3wO7RXfJcC5q30LlKeECubDf2hH+gcFHoFxBc9Tb zjvg== X-Gm-Message-State: AOAM5336q2WE7H97vCpJwdy0d5wUOt8L27evTSyVZ4+dMtwJ/tE5TeiP lNC5irAyn75G4P0KxjVT64A+vq3eGfI6Tw== X-Google-Smtp-Source: ABdhPJxTu+I8IJazWdKRopqd9K61Vb3wJdMyIURa9xGgWPULq/6UWkRvgo2kdyV6x6Vaoe1zYuBAyA== X-Received: by 2002:a1c:8115:: with SMTP id c21mr1962124wmd.153.1601023895198; Fri, 25 Sep 2020 01:51:35 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:34 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:25 +0100 Message-Id: <20200925085127.17214-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/6] libcamera: Add geometry helper functions 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" These functions are aimed at making it easier to calculate cropping rectangles, particularly in order to implement digital zoom. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- include/libcamera/geometry.h | 20 ++++++ src/libcamera/geometry.cpp | 129 +++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 02fb63c..0447ee3 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -13,6 +13,8 @@ namespace libcamera { +class Rectangle; + class Size { public: @@ -93,8 +95,17 @@ public: std::max(height, expand.height) }; } + + Size alignedDownToAspectRatio(const Size &ratio) const; + Size alignedUpToAspectRatio(const Size &ratio) const; + + Rectangle centredTo(const Rectangle ®ion, + int offsetX = 0, int offsetY = 0) const; }; +Size operator*(const Size &size, float f); +Size operator/(const Size &size, float f); + bool operator==(const Size &lhs, const Size &rhs); bool operator<(const Size &lhs, const Size &rhs); @@ -176,6 +187,11 @@ public: { } + constexpr explicit Rectangle(const Size &size) + : x(0), y(0), width(size.width), height(size.height) + { + } + int x; int y; unsigned int width; @@ -183,6 +199,10 @@ public: bool isNull() const { return !width && !height; } const std::string toString() const; + + Size size() const; + + Rectangle boundedTo(const Rectangle &boundary) const; }; bool operator==(const Rectangle &lhs, const Rectangle &rhs); diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index b12e1a6..649ee17 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -143,6 +143,88 @@ const std::string Size::toString() const * height of this size and the \a expand size */ +/** + * \brief Align down to the aspect ratio given by \a ratio + * \param[in] ratio The size whose aspect ratio to align down to + * \return A Size whose width and height are equal to the width and height + * of this Size aligned down to the aspect ratio of \a ratio + */ +Size Size::alignedDownToAspectRatio(const Size &ratio) const +{ + uint64_t ratio1 = static_cast(width) * + static_cast(ratio.height); + uint64_t ratio2 = static_cast(ratio.width) * + static_cast(height); + + if (ratio1 > ratio2) + return { static_cast(ratio2 / ratio.height), height }; + else + return { width, static_cast(ratio1 / ratio.width) }; +} + +/** + * \brief Align up to the aspect ratio given by \a ratio + * \param[in] ratio The size whose aspect ratio to align up to + * \return A Size whose width and height are equal to the width and height + * of this Size aligned up to the aspect ratio of \a ratio + */ +Size Size::alignedUpToAspectRatio(const Size &ratio) const +{ + uint64_t ratio1 = static_cast(width) * + static_cast(ratio.height); + uint64_t ratio2 = static_cast(ratio.width) * + static_cast(height); + + if (ratio1 < ratio2) + return { static_cast(ratio2 / ratio.height), height }; + else + return { width, static_cast(ratio1 / ratio.width) }; +} + +/** + * \brief Centre a rectangle of this size within another rectangular region, + * with optional offsets + * \param[in] region The rectangular region relative to which the returned + * rectangle can be position + * \param[in] offsetX The X offset of the mid-point of the returned rectangle + * relative to the mid-point of the region + * \param[in] offsetY The Y offset of the mid-point of the returned rectangle + * relative to the mid-point of the region + * + * A Rectangle of this object's size is positioned within the Rectangle + * given by \a region. It is positioned so that its mid-point coincides + * with the mid-point of \a region, and is then further offset by the + * values \a offsetX and \a offsetY. + * + * \return A Rectangle with the horizontal and vertical sizes of + * this Size instance, centred with offsets within a region + */ +Rectangle Size::centredTo(const Rectangle ®ion, int offsetX, int offsetY) const +{ + int x = (region.width - width) / 2 + region.x + offsetX; + int y = (region.height - height) / 2 + region.y + offsetY; + + return Rectangle(x, y, width, height); +} + +/** + * \brief Scale size up by the given factor + * \return The scaled Size + */ +Size operator*(const Size &size, float f) +{ + return Size(size.width * f, size.height * f); +} + +/** + * \brief Scale size down by the given factor + * \return The scaled Size + */ +Size operator/(const Size &size, float f) +{ + return Size(size.width / f, size.height / f); +} + /** * \brief Compare sizes for equality * \return True if the two sizes are equal, false otherwise @@ -365,6 +447,12 @@ bool operator==(const SizeRange &lhs, const SizeRange &rhs) * \param[in] height The height */ +/** + * \fn Rectangle::Rectangle(const Size &size) + * \brief Construct a Rectangle with zero offsets and the given \a size + * \param[in] size The desired Rectangle size + */ + /** * \var Rectangle::x * \brief The horizontal coordinate of the rectangle's top-left corner @@ -404,6 +492,47 @@ const std::string Rectangle::toString() const return ss.str(); } +/** + * \brief Retrieve the size of this rectangle + * \return A Size reporting the Rectangle horizontal and vertical sizes + */ +Size Rectangle::size() const +{ + return Size(width, height); +} + +/** + * \brief Bound a Rectangle so as not to exceeed another Rectangle + * \param[in] boundary The limit that the returned Rectangle will not exceed + * + * The Rectangle is bounded so that it does not exceeed the given \a boundary. + * This process involves translating the Rectangle if any of its edges + * lie beyond \a boundary, so that those edges then lie along the boundary + * instead. + * + * If either width or height are larger than \a bounary, then the returned + * Rectangle is clipped to be no larger. But other than this, the + * Rectangle is not clipped or reduced in size, merely translated. + * + * We note that this is not a conventional Rectangle intersection function. + * + * \return A Rectangle that does not extend beyond a boundary Rectangle + */ +Rectangle Rectangle::boundedTo(const Rectangle &boundary) const +{ + Rectangle result(*this); + + result.width = std::min(result.width, boundary.width); + result.x = std::clamp(result.x, boundary.x, + boundary.x + boundary.width - result.width); + + result.height = std::min(result.height, boundary.height); + result.y = std::clamp(result.y, boundary.y, + boundary.y + boundary.height - result.height); + + return result; +} + /** * \brief Compare rectangles for equality * \return True if the two rectangles are equal, false otherwise From patchwork Fri Sep 25 08:51:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9826 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 09CDFC3B5C for ; Fri, 25 Sep 2020 08:51:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CB55F63043; Fri, 25 Sep 2020 10:51:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="m9CofgmN"; dkim-atps=neutral Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C434B63030 for ; Fri, 25 Sep 2020 10:51:36 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id k15so2638637wrn.10 for ; Fri, 25 Sep 2020 01:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gP5B4J/bWhecyfZY4eiJ4gLYV2WzmrTl87X3aXvikXI=; b=m9CofgmNEEjSRvI9gGpfQxSv4DESKoC1q600JMtafc3RQ5Zi4D79ovA0WiHqpeLJwF ExvZkHbfYGfXRkNXnXviaMC0RXOTag7x6mS9/uHTASeNaSkiUVsJIAlBKkZ/2PW+smc5 wLRfLuvc6AiixGcrIIBq5Ab8l+VD3g+o1frvSimFaRk5ij5PJzHpKUymkbPhs4PAPfjX aQ+kVpBAvi/9sPeWGipXcpLBByqgOAlR//lYwHliYY9NPZpm0WDwB1p5O21L+mCB8+K1 oPFIjnpZPoXa19RIlHbAW9Uyav/jkIWOO6C4dkhzlcdvECSvxcoiDOYAQ97XP2SfAaoc CeMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gP5B4J/bWhecyfZY4eiJ4gLYV2WzmrTl87X3aXvikXI=; b=miINWtOO1T+Ma/vL8Dr6wUQNzX6IkmvgC3XBnZbLiayS1a7ITR8fupypj05cU2cYnL yZRtIkH0cD0gRt7e/vU6TqYDMjO5GluhMunHsAk7Tdwr2NgOTIxA/QBGS0bJwKaZNc3M /PNg+9+BtWJSIIcLeD5h6K/ZMJjTZtoesggO0eZFTOYh7eGHCmoCkgU0NnKC+WVbQFYU azfmN4UE5DCyFcxlvM/ILj2OHGVSFKB1Ab4ff01Nu2i6AsskRlPafso2cXZZ0dWeQgpX 60jLKAOrlL+gHlTByKDUv+SPCTKeVhHztd5ZeG9huRhF+1Q1PivCXv/12eh8yOrOJWZC fJvA== X-Gm-Message-State: AOAM530FJ9qRHFDwLtsZcBSIZtp9ZG59R9s9fdC6uoYDdoN89hNXRr4Q Pqistbcf4HkwMFTTgI6zIELrV4mKU+BlzA== X-Google-Smtp-Source: ABdhPJxs37QXobXyEd7ehlHDBKnwKrDTKjvO3odnqcMqND+UOEQIlZjrlfwqwr5SYnGm+wizG6RLCg== X-Received: by 2002:a5d:4709:: with SMTP id y9mr3311460wrq.59.1601023896145; Fri, 25 Sep 2020 01:51:36 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:35 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:26 +0100 Message-Id: <20200925085127.17214-6-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/6] libcamera: pipeline: raspberrypi: Implementation of digital zoom 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" During configure() we update the SensorOutputSize to the correct value for this camera mode (which we also note internally) and work out the minimum crop size allowed by the ISP. Whenever a new IspCrop request is received we check it's valid and apply it to the ISP V4L2 device. We also forward it to the IPA so that the IPA can return the values used in the image metadata. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/raspberrypi.cpp | 7 +++ .../pipeline/raspberrypi/raspberrypi.cpp | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index dd6ebea..9dd6323 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -58,6 +58,7 @@ static const ControlInfoMap RPiControls = { { &controls::Saturation, ControlInfo(0.0f, 32.0f) }, { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) }, { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) }, + { &controls::IspCrop, ControlInfo({}, Rectangle(65535, 65535, 65535, 65535), {}) }, }; } /* namespace libcamera */ diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 0555cc4..64f0e35 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -687,6 +687,13 @@ void IPARPi::queueRequest(const ControlList &controls) break; } + case controls::ISP_CROP: { + /* Just copy the information back. */ + Rectangle crop = ctrl.second.get(); + libcameraMetadata_.set(controls::IspCrop, crop); + break; + } + default: LOG(IPARPI, Warning) << "Ctrl " << controls::controls.at(ctrl.first)->name() diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 50f0718..dd5feac 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -182,6 +182,11 @@ public: std::queue embeddedQueue_; std::deque requestQueue_; + /* For handling digital zoom. */ + Size ispMinSize_; + Size sensorOutputSize_; + Rectangle lastIspCrop_; + unsigned int dropFrameCount_; private: @@ -502,6 +507,14 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) */ ret = data->isp_[Isp::Input].dev()->setFormat(&sensorFormat); + /* + * Update the SensorOutputSize to the correct value for this camera mode. + * + * \todo Move this property to CameraConfiguration when that + * feature will be made available and set it at validate() time + */ + data->properties_.set(properties::SensorOutputSize, sensorFormat.size); + /* * See which streams are requested, and route the user * StreamConfiguration appropriately. @@ -592,6 +605,16 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) return ret; } + /* + * Figure out the smallest selection the ISP will allow. We also store + * the output image size, in pixels, from the sensor. These will be + * used for digital zoom. + */ + Rectangle testCrop(0, 0, 1, 1); + data->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &testCrop); + data->ispMinSize_ = testCrop.size(); + data->sensorOutputSize_ = sensorFormat.size; + /* Adjust aspect ratio by providing crops on the input image. */ Rectangle crop{ 0, 0, sensorFormat.size }; @@ -608,6 +631,8 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) crop.y = (sensorFormat.size.height - crop.height) >> 1; data->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop); + data->lastIspCrop_ = crop; + ret = data->configureIPA(); if (ret) LOG(RPI, Error) << "Failed to configure the IPA: " << ret; @@ -1449,6 +1474,28 @@ void RPiCameraData::tryRunPipeline() /* Take the first request from the queue and action the IPA. */ Request *request = requestQueue_.front(); + if (request->controls().contains(controls::IspCrop)) { + Rectangle crop = request->controls().get(controls::IspCrop); + if (crop.width && crop.height) { + /* + * The crop that we set must be: + * 1. At least as big as ispMinSize_, once that's been + * enlarged to the same aspect ratio. + * 2. With the same mid-point, if possible. + * 3. But it can't go outside the sensor area. + */ + Size minSize = ispMinSize_.alignedUpToAspectRatio(crop.size()); + Size size = crop.size().expandedTo(minSize); + crop = size.centredTo(crop).boundedTo(Rectangle(sensorOutputSize_)); + + if (crop != lastIspCrop_) + isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop); + lastIspCrop_ = crop; + } + + request->controls().set(controls::IspCrop, lastIspCrop_); + } + /* * Process all the user controls by the IPA. Once this is complete, we * queue the ISP output buffer listed in the request to start the HW From patchwork Fri Sep 25 08:51:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9827 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 64059C3B5E for ; Fri, 25 Sep 2020 08:51:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2DEE76303E; Fri, 25 Sep 2020 10:51:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="Cb82YblN"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E49363043 for ; Fri, 25 Sep 2020 10:51:37 +0200 (CEST) Received: by mail-wm1-x335.google.com with SMTP id w2so2221739wmi.1 for ; Fri, 25 Sep 2020 01:51:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9KYLEfSfm9lWEFuKcyq5x/Li6dFc8LJrxWJSayBldfI=; b=Cb82YblNKMLHsJN7E+MsJO2HH5L4PwnOcJ7U6T6MBYzDfjJy4tqBjkVVr51YQoOhFz r38bL6xvUYPq6yza8IkA6dJu8uv09goGUg8g7cD1boMm+NnxKNyh4pgPs3Pv/fsLiJxe 42XwWPQyum60T5F4YJqHlJdnmDjO4c/zSO/PShcbDIkcKr5UAPninXc0aIAPlQv+CIrL M8GGRklycQomD+P9UKJ3vzI1sXodQLj/RyZDS30cWX7W2/7E3VhJbGv+kbGGGqLmS5+R x3Qk3XkAu5Yd0nB4OYulwcZ90KdsYu7thI8MvIxgw4IADFXimiVwvNSD3P0mXhAUSdn0 Vnzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9KYLEfSfm9lWEFuKcyq5x/Li6dFc8LJrxWJSayBldfI=; b=lvvLNLq+gUjgezfY697H0BunU9APC9yOKi7yPsFWHtjgbcmCDbyMbDf3pg4/Isj7gW 6nlfOyfv3UV/AmgNcxoQCWCMDwfsnsGyipOfc4mFZN+uTL71RsCVWvdTxSUdLPmZSHIj lmSWvKQ+1CFHOXbC2G6zYZgiJvuYM0vripYai+xPbQYHfkJ4kNCoJBH+OzKJpab/LfLb A7yKKRWHCodtmMiwEJ0taPqOXn82ff5SssVufkodhJalAL/EO57pD4fBIh2nPt6llaRL TxJr7L7V7uxTaAO2WaAnNEATd/1c2zav0HQDWmaEASKxlsZ1yx91bA5NuttcY6Dlysxb nUwA== X-Gm-Message-State: AOAM532VuLasblP9wG1s+0nG4KoWeMvyrG58WTj4R8sOaQdDfwSlg9ko UI8qHMQCPrxSXYr7sdXa8ATJL3C67A6XZQ== X-Google-Smtp-Source: ABdhPJyHeheRKX71RbD7I2gSCkSAyXoTs5oJaL1IC2UcFKL42FGNS0u/naPUhIH+ViwVC3ZRHDI65w== X-Received: by 2002:a1c:740c:: with SMTP id p12mr1939475wmc.176.1601023897113; Fri, 25 Sep 2020 01:51:37 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id n4sm2001383wrp.61.2020.09.25.01.51.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 01:51:36 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 09:51:27 +0100 Message-Id: <20200925085127.17214-7-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200925085127.17214-1-david.plowman@raspberrypi.com> References: <20200925085127.17214-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/6] cam: Add command line option to test IspCrop control 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" This allows the user to request digital zoom by adding, for example, "-z 0.25,0.25,0.5,0.5" which would give a 2x zoom, still centred in the middle of the image. Signed-off-by: David Plowman Reviewed-by: Jacopo Mondi --- src/cam/capture.cpp | 25 +++++++++++++++++++++++-- src/cam/capture.h | 2 +- src/cam/main.cpp | 3 +++ src/cam/main.h | 1 + 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp index 5510c00..3b50c59 100644 --- a/src/cam/capture.cpp +++ b/src/cam/capture.cpp @@ -10,6 +10,9 @@ #include #include +#include +#include + #include "capture.h" #include "main.h" @@ -58,7 +61,7 @@ int Capture::run(const OptionsParser::Options &options) FrameBufferAllocator *allocator = new FrameBufferAllocator(camera_); - ret = capture(allocator); + ret = capture(allocator, options); if (options.isSet(OptFile)) { delete writer_; @@ -70,7 +73,7 @@ int Capture::run(const OptionsParser::Options &options) return ret; } -int Capture::capture(FrameBufferAllocator *allocator) +int Capture::capture(FrameBufferAllocator *allocator, const OptionsParser::Options &options) { int ret; @@ -120,6 +123,24 @@ int Capture::capture(FrameBufferAllocator *allocator) requests.push_back(request); } + /* Set up digital zoom if it was requested on the command line. */ + if (options.isSet(OptZoom)) { + std::string zoom = options[OptZoom].toString(); + float x, y, width, height; + + if (sscanf(zoom.c_str(), "%f,%f,%f,%f", &x, &y, &width, &height) == 4) { + Size sensorArea = camera_->properties().get(properties::SensorOutputSize); + Rectangle crop(x * sensorArea.width, + y * sensorArea.height, + width * sensorArea.width, + height * sensorArea.height); + + requests.front()->controls().set(controls::IspCrop, crop); + } else { + std::cout << "Invalid zoom values - ignoring" << std::endl; + } + } + ret = camera_->start(); if (ret) { std::cout << "Failed to start capture" << std::endl; diff --git a/src/cam/capture.h b/src/cam/capture.h index 0aebdac..5280616 100644 --- a/src/cam/capture.h +++ b/src/cam/capture.h @@ -29,7 +29,7 @@ public: int run(const OptionsParser::Options &options); private: - int capture(libcamera::FrameBufferAllocator *allocator); + int capture(libcamera::FrameBufferAllocator *allocator, const OptionsParser::Options &options); void requestComplete(libcamera::Request *request); diff --git a/src/cam/main.cpp b/src/cam/main.cpp index 244720b..8f326d9 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -201,6 +201,9 @@ int CamApp::parseOptions(int argc, char *argv[]) parser.addOption(OptStrictFormats, OptionNone, "Do not allow requested stream format(s) to be adjusted", "strict-formats"); + parser.addOption(OptZoom, OptionString, + "Specify digital zoom by supplying IspCrop control as x,y,width,height e.g. 0.25,0.25,0.5,0.5", + "zoom", ArgumentRequired, "zoom"); options_ = parser.parse(argc, argv); if (!options_.valid()) diff --git a/src/cam/main.h b/src/cam/main.h index ea8dfd3..a1fd899 100644 --- a/src/cam/main.h +++ b/src/cam/main.h @@ -17,6 +17,7 @@ enum { OptListProperties = 'p', OptMonitor = 'm', OptStream = 's', + OptZoom = 'z', OptListControls = 256, OptStrictFormats = 257, };