Patch Detail
Show a patch.
GET /api/patches/9515/?format=api
{ "id": 9515, "url": "https://patchwork.libcamera.org/api/patches/9515/?format=api", "web_url": "https://patchwork.libcamera.org/patch/9515/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20200907164450.13082-5-david.plowman@raspberrypi.com>", "date": "2020-09-07T16:44:50", "name": "[libcamera-devel,RFC,4/4] libcamera: pipeline: raspberrypi: Implementation of digital zoom", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "eeb30d22de0083828edd28495a72685c4ece417a", "submitter": { "id": 42, "url": "https://patchwork.libcamera.org/api/people/42/?format=api", "name": "David Plowman", "email": "david.plowman@raspberrypi.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/9515/mbox/", "series": [ { "id": 1270, "url": "https://patchwork.libcamera.org/api/series/1270/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1270", "date": "2020-09-07T16:44:46", "name": "Digital zoom", "version": 1, "mbox": "https://patchwork.libcamera.org/series/1270/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/9515/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/9515/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 425DEBDB1E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 7 Sep 2020 16:45:01 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 026BE62C15;\n\tMon, 7 Sep 2020 18:45:01 +0200 (CEST)", "from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com\n\t[IPv6:2a00:1450:4864:20::42b])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2D43960372\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 7 Sep 2020 18:44:59 +0200 (CEST)", "by mail-wr1-x42b.google.com with SMTP id m6so16472951wrn.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 07 Sep 2020 09:44:59 -0700 (PDT)", "from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\tv3sm27707033wmh.6.2020.09.07.09.44.57\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 07 Sep 2020 09:44:57 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"mkTU+JS4\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=cLq8fMZ6wax4QpFQ10/ZmQl82O46CeZqaT5ztQBHqlQ=;\n\tb=mkTU+JS4xNFJTI838MsBxzKXWdCYGOuAxz9oidmS03AyoIkScaUejjivABci/8AdgC\n\tDfDfw0WZexTOAF0ENYghjyA+bdpwSN6ucJxa7R/M1F5dmKufIdzLXzkzvL40s1+fT789\n\tSjHYkHhHRr2kvpc1dHEn1spmY/NpwcRNmFUY40DwZVBmE3uI1L6COCizjBZqrADtSs9b\n\tvV2cPomwz6l08mBZ+OXRmJEvhcjOt0RnOFu8BHdpMgnY+1obihvKU0iFzg9yELJeyRxX\n\tccB5/sIOnQlMoTHWPiNsV21A2Jf1ZOeVyQlvILeaWDn7uVnr5B+DDTHAH4QSpkE/nV7Z\n\tyRKA==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=cLq8fMZ6wax4QpFQ10/ZmQl82O46CeZqaT5ztQBHqlQ=;\n\tb=G2xsR1wYWP0P6XtqB6HxSwWbEo58EcOim5IleXucu8nRZBeDEWVAtN5wA8OBYanF8l\n\tj9G/YE1E05tmIp+Lell1AcEOdH7SVJHCQWhLZaLERlXFo/r81ZJcB4fIZTxc1ibTpSOH\n\t5A4oR5yvNemCIeklOoRVdIjCIJG9ctJ5U8VSaHQ1GEjquo6AqI6/iIRvuKPEzkfjmrLO\n\tvLDGo31mIbnpsNNb4VZl5zV2URH1brFjN+MA/oRQMIlDmqIytRVGuJh74Fdq9o62V4Zc\n\t+FqD5CcTWTyV+j+QTdzLJ09aW7fqMxZnn8mbHTls81MM1nScemjeLtfeez2ZTirseA+p\n\t3Kcg==", "X-Gm-Message-State": "AOAM532VFJzUUeHS47RsJly1NCf2IchoQukuX6LFW+mMz6eMk+f8kzdL\n\tHR9GdCH93aZmSnP7Qs3wmpuoWLWQYxRtyQ==", "X-Google-Smtp-Source": "ABdhPJyj8EjZOEn3VqX4p1Ac7S/iEVtp+Uy2bBwKP+mb+iNWYP4OkiS+ibxmRNFaE7xyajp0IuVPKw==", "X-Received": "by 2002:a5d:6806:: with SMTP id\n\tw6mr22489405wru.395.1599497098538; \n\tMon, 07 Sep 2020 09:44:58 -0700 (PDT)", "From": "David Plowman <david.plowman@raspberrypi.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Mon, 7 Sep 2020 17:44:50 +0100", "Message-Id": "<20200907164450.13082-5-david.plowman@raspberrypi.com>", "X-Mailer": "git-send-email 2.20.1", "In-Reply-To": "<20200907164450.13082-1-david.plowman@raspberrypi.com>", "References": "<20200907164450.13082-1-david.plowman@raspberrypi.com>", "MIME-Version": "1.0", "Subject": "[libcamera-devel] [RFC PATCH 4/4] libcamera: pipeline: raspberrypi:\n\tImplementation of digital zoom", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "During configure() we make a note of the minimum crop size allowed by\nthe ISP, and the image output size of the chosen sensor mode.\n\nWhenever a new SensorCrop request is received we check it's valid and\napply it to the ISP V4L2 device. We also forward it to the IPA so that\nthe IPA can return the values used in the image metadata.\n---\n include/libcamera/ipa/raspberrypi.h | 1 +\n src/ipa/raspberrypi/raspberrypi.cpp | 7 ++++\n .../pipeline/raspberrypi/raspberrypi.cpp | 39 +++++++++++++++++++\n 3 files changed, 47 insertions(+)", "diff": "diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h\nindex ca62990..361b47d 100644\n--- a/include/libcamera/ipa/raspberrypi.h\n+++ b/include/libcamera/ipa/raspberrypi.h\n@@ -57,6 +57,7 @@ static const ControlInfoMap RPiControls = {\n \t{ &controls::Saturation, ControlInfo(0.0f, 32.0f) },\n \t{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },\n \t{ &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },\n+\t{ &controls::SensorCrop, ControlInfo(Rectangle(0, 0, 0, 0), Rectangle(65535, 65535, 65535, 65535), Rectangle(0, 0, 0, 0)) },\n };\n \n } /* namespace libcamera */\ndiff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\nindex 4557016..4a364b7 100644\n--- a/src/ipa/raspberrypi/raspberrypi.cpp\n+++ b/src/ipa/raspberrypi/raspberrypi.cpp\n@@ -687,6 +687,13 @@ void IPARPi::queueRequest(const ControlList &controls)\n \t\t\tbreak;\n \t\t}\n \n+\t\tcase controls::SENSOR_CROP: {\n+\t\t\t/* Just copy the information back. */\n+\t\t\tRectangle crop = ctrl.second.get<Rectangle>();\n+\t\t\tlibcameraMetadata_.set(controls::SensorCrop, crop);\n+\t\t\tbreak;\n+\t\t}\n+\n \t\tdefault:\n \t\t\tLOG(IPARPI, Warning)\n \t\t\t\t<< \"Ctrl \" << controls::controls.at(ctrl.first)->name()\ndiff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex 7f151cb..3196a61 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -335,6 +335,11 @@ public:\n \tstd::queue<FrameBuffer *> embeddedQueue_;\n \tstd::deque<Request *> requestQueue_;\n \n+\t/* For handling digital zoom. */\n+\tSize ispMinSize_;\n+\tSize sensorOutputSize_;\n+\tRectangle lastSensorCrop_;\n+\n private:\n \tvoid checkRequestCompleted();\n \tvoid tryRunPipeline();\n@@ -737,6 +742,16 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \t\treturn ret;\n \t}\n \n+\t/*\n+\t * Figure out the smallest selection the ISP will allow. We also store\n+\t * the output image size, in pixels, from the sensor. These will be\n+\t * used for digital zoom.\n+\t */\n+\tRectangle testCrop(0, 0, 1, 1);\n+\tdata->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &testCrop);\n+\tdata->ispMinSize_ = testCrop.size();\n+\tdata->sensorOutputSize_ = sensorFormat.size;\n+\n \t/* Adjust aspect ratio by providing crops on the input image. */\n \tRectangle crop{ 0, 0, sensorFormat.size };\n \n@@ -753,6 +768,8 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \tcrop.y = (sensorFormat.size.height - crop.height) >> 1;\n \tdata->isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop);\n \n+\tdata->lastSensorCrop_ = crop;\n+\n \tret = data->configureIPA();\n \tif (ret)\n \t\tLOG(RPI, Error) << \"Failed to configure the IPA: \" << ret;\n@@ -1545,6 +1562,28 @@ void RPiCameraData::tryRunPipeline()\n \t */\n \tRequest *request = requestQueue_.front();\n \n+\tif (request->controls().contains(controls::SensorCrop)) {\n+\t\tRectangle crop = request->controls().get<Rectangle>(controls::SensorCrop);\n+\t\tif (crop.width && crop.height) {\n+\t\t\t/*\n+\t\t\t * The crop that we set must be:\n+\t\t\t * 1. At least as big as ispMinSize_, once that's been\n+\t\t\t * enlarged to the same aspect ratio.\n+\t\t\t * 2. With the same mid-point, if possible.\n+\t\t\t * 3. But it can't go outside the sensor area.\n+\t\t\t */\n+\t\t\tSize minSize = ispMinSize_.aspectRatioUp(crop.size());\n+\t\t\tSize size = crop.size().expandedTo(minSize);\n+\t\t\tcrop = size.centre(crop).clamp(Rectangle(sensorOutputSize_));\n+\n+\t\t\tif (crop != lastSensorCrop_)\n+\t\t\t\tisp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &crop);\n+\t\t\tlastSensorCrop_ = crop;\n+\t\t}\n+\n+\t\trequest->controls().set(controls::SensorCrop, lastSensorCrop_);\n+\t}\n+\n \t/*\n \t * Process all the user controls by the IPA. Once this is complete, we\n \t * queue the ISP output buffer listed in the request to start the HW\n", "prefixes": [ "libcamera-devel", "RFC", "4/4" ] }