From patchwork Tue Sep 22 10:03:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9699 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 25030BF01C for ; Tue, 22 Sep 2020 10:04:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B845162FD5; Tue, 22 Sep 2020 12:04:08 +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="tdNuATfM"; dkim-atps=neutral Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EFB6660367 for ; Tue, 22 Sep 2020 12:04:07 +0200 (CEST) Received: by mail-wm1-x329.google.com with SMTP id q9so2691382wmj.2 for ; Tue, 22 Sep 2020 03:04:07 -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=LigCNjkZO94leaY9q1uFql7UckMWWfQGwZmh1nkglmo=; b=tdNuATfM2e0I9zvrLivMiCZxSHWExLgBNnaaydB16jFI6mmDx/g3eFrQ5zihHn/7bp RfiMKh/joKNPGWHyRXKf07hHfQKxiWG/88ZZzX7Z9Fg1PKC8iqxOGpFRpBZ/DCJ5Mrd4 kucA+bFkeQ7dtm7K7xHSdbd76cj9wxfDWll+c+I4mVPiX5t4aXb8t0JL6fTqvKRzvKWA hih7tTUCdQwF1ZDhZcFEjt/GBKqI9Sm4g4w23f0MZqZNJm4mmq/0lq7caRMXZXJ1bez8 YPMNJQzgr3pl2ywS79ohCDnD7nx6vP61qDoUk9KwnA9avqEqsIqCQ/Jz7ASKyhc0Aliq QfEg== 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=LigCNjkZO94leaY9q1uFql7UckMWWfQGwZmh1nkglmo=; b=fOEyvmUE8CaVs/7lUkFdckSnP09maXDuZRbw4A5JTINphNam+UCga1vGHy0XZuFJMY NLqZw3vdG98BvystGacrranpb3ZlN2drXl3aq/0INh/ohZ7AC/mskYolVEYgJWrul9KD BngOdbN5nh7YL4hvOZB9WDzKJuush9mnohAj4uyCewuJkDkSYqPFLLFktMCpJiW2oFOL bhPccWuPGJ7hjInugQSOEI5EfUWAAKZkmAuIb7DoAKbCb6CkQVCubeduH5nUix97sbEe 0A4jby9v0kQ9ul/LbEr/ztOMKnAVaDRmRmlmpyELP6GWcCy521zgnk/hfLog1bn1NSw9 2flQ== X-Gm-Message-State: AOAM530rPMvDIwZIjYITNKyheo3FWmZpKxfePepousIuwfUKDbqrrUVm h+EQL4x6tmNwd4KD4TG05bbu2bVHaK0Wbw== X-Google-Smtp-Source: ABdhPJxg+Ryvs0ZK0fptNcXABsLvmrfAiD9Aidnj76CQWq936pK7ejD6FPXimircaglcJq2E9m3bLw== X-Received: by 2002:a05:600c:2109:: with SMTP id u9mr102276wml.147.1600769047361; Tue, 22 Sep 2020 03:04:07 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:06 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:03:55 +0100 Message-Id: <20200922100400.30766-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index 74ad019..c185549 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -640,4 +640,16 @@ 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. + Note that this property changes with every newly selected + camera mode. It can be used to implement digital zoom. + ... From patchwork Tue Sep 22 10:03:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9700 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 454C5BF01C for ; Tue, 22 Sep 2020 10:04:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 10E3062FD5; Tue, 22 Sep 2020 12:04:12 +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="cZ+2tvux"; 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 F3C7D62FD7 for ; Tue, 22 Sep 2020 12:04:08 +0200 (CEST) Received: by mail-wr1-x442.google.com with SMTP id s12so16365765wrw.11 for ; Tue, 22 Sep 2020 03:04:08 -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=4lH2W2zOi/lSgf+bdq75Jba1fCn8R09Q1otyB8VpLX4=; b=cZ+2tvuxUbwokv0NTu/2TPWUV2YfrZPp8RwoJM5Hi7r8iHLoBNAI+MxxrdVkotdrkx Atzdwmlw1/wOv55r3sXOp2kyu6ZzobxxutDOD+CyZhYCETUC3CxKrqbIXRYFGH2HNVaw iAaJ6gifiqAyGayBjamS/gqwh4ur62WqdIlN/KyTrZB50JtjIhrreHdIx5G0iZfbQbC2 lDYYY++GSTH0HHizfgAXtneALR62qydS9Pi3VFXoYjhO6+vIMpUnhwKvaeUYXLV6Od+4 yYhpUS49DMQ9x8qvPA4Crw8tjdqeJdZ9KhI6Y0j2BVwRrtxzkLhl8iXoJOyrZzVi9Cb3 8KMw== 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=4lH2W2zOi/lSgf+bdq75Jba1fCn8R09Q1otyB8VpLX4=; b=MgRkT1MyZ8SWacH46IBFLrqy1xvgg2izoP6ZnQ9IfYGFoakK0wHJ7d49LpJRaReZOm jFMz8AKYNaGrHWM6wciWDrOIYenMA5Tr7qKXumoJz/3NyxTG0gqGoyfnlRKUHXjnoN1J ckxwNz7X4EN3sTeYCxZcVvKdB9QFy5i0ANFcz5ArRK9dduqLaLtPyPYpxNQrq4DLqRIm btbrRohfM0tJmib1l2GYRkJ2dKEg7CYda0xM43pRCDSIKuvTJ65F/13s5f+eImyNYtri 1yNG0wmBogK6ZjrIkNt9lB8WX/vxC95V++gO1e/ON53otxAjE+iPe1KTn8JmPvfSEmdO K4BA== X-Gm-Message-State: AOAM53215M1PlOCDfTJdn1rFrvlS3Xi8XNJyXFwfsGcm74gQLtljdNI0 krTaMX6hscVPrFxXk13xJoGKL+RQVGzT5A== X-Google-Smtp-Source: ABdhPJza+zE+hsj6GpsM5yI2RV3cK3Poz1h/QcTZX3EeZXx4X9GK0YLr4NtkCMQXr3EA1sFMV3bPkg== X-Received: by 2002:a5d:4842:: with SMTP id n2mr4485520wrs.260.1600769048426; Tue, 22 Sep 2020 03:04:08 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:07 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:03:56 +0100 Message-Id: <20200922100400.30766-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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 Tue Sep 22 10:03:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9701 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 B7C7BBF01C for ; Tue, 22 Sep 2020 10:04:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 84B9E62FD3; Tue, 22 Sep 2020 12:04:12 +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="jM6T3HlB"; dkim-atps=neutral Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A4B3D62FD7 for ; Tue, 22 Sep 2020 12:04:09 +0200 (CEST) Received: by mail-wr1-x441.google.com with SMTP id e16so16398582wrm.2 for ; Tue, 22 Sep 2020 03:04:09 -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=jM6T3HlBuBxiUvGeJayh1XqDKGsd5TOU+qmvnRFBAA08FZ2C9QvlD1wZ6JxC3/CCiU qaUPrIpAtuBoPKC5sB2giExJtxuG/V1YABfz66R9R7fFkkJG7101+X85ftTjpfN4MFjl nU6A8nbDuEDW5nfNzDdzZfYId2zF65hrpZ0E5xRD0ANO7RzFiZ48xRLafXb/+jPRU187 HBA1kV4Akn16cs+5u4HXWQ7DUoS/jevUPubVpUDeepCcG53PmMWcvZDygsgfIUuxbZKc N+lfZbRBdQv5XM7TFCl10DgNR71yAV6DFOkaI9VzOuROtsIXUZwc7Xt4NgtnZVDS+ZEs Ndvw== 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=Bbp2PW+g2+yZdnUzxhHL6VJNAjDL+wGg4L3WGme5sEFRd/FB5X0DtfTl5UkRcOtBqe /dE3qMCKWu19XKbjCnQkjI73Aoq9GKIwtl7pzAmnfgui94WBY7iJuFbLq5jk0gL8YGK1 BfPq/chIFBcBmkKIj7xvxLIJLpLeRyAbsF9GqK4Q+WYP1DHR07q/0ELaKwEQeJ9TplT9 ETwtVc8CSbhdeHmqA8wJ0VuAp7z62Et23ygWEjCcklXDXxI2m+lj14cFIOI9WFPo7m31 LYUGD/sY+NlxMni2bwrUXKm0Ha0mn2in3Aj1gjGItvBSf6BB6a6lYUyuGEynUzywXZt/ AKSg== X-Gm-Message-State: AOAM532hYP97NPC5dvA52M8B+KKmgYoTMFTrUmX/O0yMhQY2EHk5/qBS Maei8gOZlz5LOSrMZARnaanc8s4UqlqkLw== X-Google-Smtp-Source: ABdhPJwpffMZgPiMgSkUiLmnN+FxnzqACrAAGmjd3tVlYdEmB3yPGXsFQgeAlYap3ueSEAUxOBbssA== X-Received: by 2002:adf:e690:: with SMTP id r16mr4372949wrm.15.1600769049207; Tue, 22 Sep 2020 03:04:09 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:08 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:03:57 +0100 Message-Id: <20200922100400.30766-4-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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 Tue Sep 22 10:03:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9702 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 58221BF01C for ; Tue, 22 Sep 2020 10:04:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0BDEF62FE2; Tue, 22 Sep 2020 12:04:13 +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="MT6g2cud"; dkim-atps=neutral Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D52DE62FD4 for ; Tue, 22 Sep 2020 12:04:10 +0200 (CEST) Received: by mail-wm1-x333.google.com with SMTP id s13so2683910wmh.4 for ; Tue, 22 Sep 2020 03:04:10 -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=F6UgUxLglMFwqKHvcjbNLJCpNLX9Vnk/4za5rmYDkjI=; b=MT6g2cudWwvq7NTFIG7LeLTt6yT51wLSmUQyWjzZQ5xOYX18EkZyoUWc7BdoeEtFdI 8eGa1ShQqLANXg+MFr+cRI+UHJeuHTP4VBLp3EKSA2xHR4u7RpFQZjq6RYwk6lScGs4z 5x4/dEkgOL1EzzEn2zt5dHpGoE1d5+hwvP/98LsRWwFuuSJvjSFU03Sl+kvyJI/QLWLG l0N2GoZmqtNyyAioKPbtzCVaIEqdKOIE/39Z9hs8igv2VqYPlhmIPflC55BlvYEwnCGq wjRkepiDmFaUH8lOWYRDCdUB8g48AhwDTYURxruPmTThEUJfOqKTUIKu9ryeUVfmSgka 8shA== 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=F6UgUxLglMFwqKHvcjbNLJCpNLX9Vnk/4za5rmYDkjI=; b=qtZZlljEfYxezKNED5X4dR8bpVNpKgJXiEbQAyF8OGlHTC081vnP1bxr6S1QzaqWVM M2PWuQrjQUEmql0GCa84DnoR+46atLNwPOXC39AhSq94Rqmv72rzV8wW+0dPBNLZccvg gfIpK2RhiHUAesxOtWG1EI+9ByPYgZNdYYWm1TLaGa2TypbU4QoQ7vtokHniuHYbzDSj pFKxqjuSU7oPHGw47UYY1xUcN+7vUDjnCJglef7J0vZ9xW5bn6bBg81wujBxiDhlATZR tp6DTHhvyMf2BytaiV2KskXWoqnDM7EdV+uP89+keLBw2sYtBzUSTINtULMwPmwlrb/J EL8g== X-Gm-Message-State: AOAM531xg7XkDuaWOuAz3BvHE3kOEfSILGchG5OOgD2PdAWCOIPprHS1 D9PrB1Wge4zQnQcrOSD3I8oOh2LRaHHFpw== X-Google-Smtp-Source: ABdhPJwUtFfXJ8VprskvmsrnAY0d/22lr7W82zobIyMDF+2/pbpl8SEznotOmbeUguj4TcvwEeOlJQ== X-Received: by 2002:a1c:6445:: with SMTP id y66mr185760wmb.12.1600769050205; Tue, 22 Sep 2020 03:04:10 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:09 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:03:58 +0100 Message-Id: <20200922100400.30766-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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 | 131 +++++++++++++++++++++++++++++++++++ 2 files changed, 151 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..0c058dd 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -143,6 +143,90 @@ 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 +{ + Size result; + + 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 +{ + Size result; + + 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 + */ +Size operator*(const Size &size, float f) +{ + return Size(size.width * f, size.height * f); +} + +/** + * \brief Scale size down by the given factor + */ +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 +449,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 size + * \param[in] size The desired Rectangle size + */ + /** * \var Rectangle::x * \brief The horizontal coordinate of the rectangle's top-left corner @@ -404,6 +494,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 Tue Sep 22 10:03:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9703 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 475DCBF01C for ; Tue, 22 Sep 2020 10:04:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1009A62FDD; Tue, 22 Sep 2020 12:04:15 +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="UH66klOF"; 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 C05F462FDE for ; Tue, 22 Sep 2020 12:04:11 +0200 (CEST) Received: by mail-wm1-x334.google.com with SMTP id v12so870331wmh.3 for ; Tue, 22 Sep 2020 03:04:11 -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=Z8SrpSgEre5Ub0KUWcgKZOT5DdvwoJNRhtRvy7mkJDc=; b=UH66klOFOyHdgLxev0DIrrKMRajL7Q7tvgqW3/9zYyPdYYPl4E04+XRl2Ir3obNmsr foRCo3nxRc4msL4zTtwvAqsCXwed/F7r9cj6dXFnN6YF0c3NiAQUzWRHvR6gxlBeY6QX 23enUqK7caOwjMd5uVJWraB8BEVsJquRBKpXlRdv8FTaPx2lE652hE1dI98NQ0biz6wk sO0pb/E/PbzE5Rm6Oj7v5bzOoRdG5HeljsUvMw5wdeDDQ/r7t+XXf6jDzDJ9GrpTluRv USIioCb71Xr0Du0+CHl03vVjoF2jwPs1zZOeaxx9UAdzV7NXzfx4vLDqxbh4sPEqQUXS jEEA== 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=Z8SrpSgEre5Ub0KUWcgKZOT5DdvwoJNRhtRvy7mkJDc=; b=pGRROBGk2tEk8QVOsVsYtCo7PiH2QFhEp2OsWSrkKwgOKHQf2QQy+qVO7Q1jQXB4Co iDIHHQ/x0PG1H1Wi7WY7HZvcyDN5E105mIV5OYS0liOLVYmBU9MXO4MuJ5AbhiSVEyEU nvFwJVxxx6Wh0WyVi01oh2mvT/DH1K5sckQs0vUXzHtuCQ1GueDvWInDeHPln9m7/NHn BhK43sZv9xadBirWdSZj35KQBi0FYG58hnCh3+yNnESDGqnDdD+s8FqTYTElb5Rh8NMF /w36ovSdEWInR+vJFXSajE73U/Qn4veou7psMvNpr5U8OVL4Gb2AYSLmZ+M3uruZFHGP YaDw== X-Gm-Message-State: AOAM533fqh1SMcfhonJ8OcSDImxBpjpfPA0GEIzLZxrYZ9jAh65G2gL2 4aKxs4tPIozFEKcbRKP44uZlwEIir+kgnA== X-Google-Smtp-Source: ABdhPJyVyHBAWEg2ZqcSjKxIEC07SODzp2KGWCGZ+WHUex3ndoVFIr9qWSpoujHuN0JoL5VgO51Rxg== X-Received: by 2002:a05:600c:245:: with SMTP id 5mr133657wmj.33.1600769051128; Tue, 22 Sep 2020 03:04:11 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:10 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:03:59 +0100 Message-Id: <20200922100400.30766-6-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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..91a1892 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(0, 0, 0, 0), Rectangle(65535, 65535, 65535, 65535), Rectangle(0, 0, 0, 0)) }, }; } /* 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..1674f8f 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: @@ -496,6 +501,14 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) LOG(RPI, Info) << "Sensor: " << camera->id() << " - Selected mode: " << sensorFormat.toString(); + /* + * 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); + /* * This format may be reset on start() if the bayer order has changed * because of flips in the sensor. @@ -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 Tue Sep 22 10:04:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9704 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 C1619BF01C for ; Tue, 22 Sep 2020 10:04:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8362962FE5; Tue, 22 Sep 2020 12:04:15 +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="qjMt04Ij"; dkim-atps=neutral Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EA26062FDA for ; Tue, 22 Sep 2020 12:04:12 +0200 (CEST) Received: by mail-wm1-x332.google.com with SMTP id e17so2708434wme.0 for ; Tue, 22 Sep 2020 03:04:12 -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=L4AmPElkGZryXc7UPUCU4tjAIGgErk1azYH9/WZBAVw=; b=qjMt04IjzzAH8CRq5IAJVtAMdbd/+Ktp0GqG0pkRIR25oqdr2kC9SLjTgC/K1Ro70n YqcfT5VdDrue6tL1gqkmGDL+qbvTX8PfkrZfxbrc5AcPWGIBqOXkHO52S1zRYU9sGFlv fQo7f0rSPQc0vdYaZBBqsXnYfGO0EpJC4pxVO9/TdCRBEgN+ro05GiD5YSYDPJWx+EFI HzajpYnhbLWlPItj3HPFJd2hRF5PkMezD1Z6GqPIBURePIa6/4xXIeNtaUkLIftJR2mt iE4iiTh9PLNbPFzVUT/Z3P0w6YfHbIj+DBEnVYGZC8K492LZSuk0LlfmNUswsjR4fnej 08ig== 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=L4AmPElkGZryXc7UPUCU4tjAIGgErk1azYH9/WZBAVw=; b=jNqWVEHm1eEjq0899VdTvDFWDZ3zwlozxyGwlRSLOYjm0Egui3QyJ2GjIVApt9Vr1X LdcEhToyLGPvlZpIeeCAZwbrUQ1avvyOU3w1HwAxW4VekAp1j1QW/CJM/wFe6uZJpYmP +m7gUEuPgEQgfRizKcn8xLnF4/Tn6wSZBmWA6KvUbHXGNQidWtwZF8AsWDNf6zuIGevU ihSAgi7AUTmZYyrVg3B6T0HRtZFwxzTTl/UNDhHomJZsqi3fjIVwtL1M/ZdZkGaCPqQy rt1xea1FDVPLVrbf2KCmyxMn7aYVsewFk4YsnlbMPnnKSY26y1nYoEJZ6QqBHhui7MVn 683A== X-Gm-Message-State: AOAM532XC7cJytrEUvEEUiPQDcj3Eyt88ClYTloZurFlHYp3j2FUphfx edYCyidzyI88gPRc8fF9gYTVub6BtZv7iw== X-Google-Smtp-Source: ABdhPJyzX2j1dAqIIsbBfz62f0/dNuXPS3gGkwHrcYPrXsHBOM4MgmoW6NuVRI/Oq96yRr2avbG6LA== X-Received: by 2002:a05:600c:2909:: with SMTP id i9mr151948wmd.160.1600769052078; Tue, 22 Sep 2020 03:04:12 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id g14sm26369595wrv.25.2020.09.22.03.04.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2020 03:04:11 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 11:04:00 +0100 Message-Id: <20200922100400.30766-7-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200922100400.30766-1-david.plowman@raspberrypi.com> References: <20200922100400.30766-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/6] qcam: 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 --- src/qcam/main.cpp | 3 +++ src/qcam/main_window.cpp | 20 ++++++++++++++++++++ src/qcam/main_window.h | 1 + 3 files changed, 24 insertions(+) diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp index f60d3ce..9f8435d 100644 --- a/src/qcam/main.cpp +++ b/src/qcam/main.cpp @@ -38,6 +38,9 @@ OptionsParser::Options parseOptions(int argc, char *argv[]) "renderer", ArgumentRequired, "renderer"); parser.addOption(OptStream, &streamKeyValue, "Set configuration of a camera stream", "stream", true); + parser.addOption(OptZoom, OptionString, + "Specify crop for digital zoom as fractions x,y,width,height e.g. 0.25,0.25,0.5,0.5", + "zoom", ArgumentRequired, "zoom"); OptionsParser::Options options = parser.parse(argc, argv); if (options.isSet(OptHelp)) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 985743f..fb54b15 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include "dng_writer.h" @@ -502,6 +504,24 @@ int MainWindow::startCapture() 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 { + qWarning() << "Invalid zoom values - ignoring"; + } + } + /* Start the title timer and the camera. */ titleTimer_.start(2000); frameRateInterval_.start(); diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 5c61a4d..e46eb70 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -39,6 +39,7 @@ enum { OptHelp = 'h', OptRenderer = 'r', OptStream = 's', + OptZoom = 'z', }; class CaptureRequest