Show a patch.

GET /api/1.1/patches/18348/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 18348,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/18348/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/18348/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20230307103023.3932-3-naush@raspberrypi.com>",
    "date": "2023-03-07T10:30:22",
    "name": "[libcamera-devel,v3,2/3] ipa: raspberrypi: Better heuristics for calculating Unicam timeout",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "ceba26dba05507f4a86f49c34abfb8d81d5ea271",
    "submitter": {
        "id": 34,
        "url": "https://patchwork.libcamera.org/api/1.1/people/34/?format=api",
        "name": "Naushir Patuck",
        "email": "naush@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/18348/mbox/",
    "series": [
        {
            "id": 3791,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3791/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3791",
            "date": "2023-03-07T10:30:20",
            "name": "Raspberry Pi: Improving camera timeouts",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/3791/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/18348/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/18348/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 9BD65BDE17\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  7 Mar 2023 10:30:24 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B3A51626BD;\n\tTue,  7 Mar 2023 11:30:22 +0100 (CET)",
            "from mail-wr1-x430.google.com (mail-wr1-x430.google.com\n\t[IPv6:2a00:1450:4864:20::430])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E4A93626B0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  7 Mar 2023 11:30:20 +0100 (CET)",
            "by mail-wr1-x430.google.com with SMTP id f11so11593612wrv.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 07 Mar 2023 02:30:20 -0800 (PST)",
            "from localhost.localdomain ([93.93.133.154])\n\tby smtp.gmail.com with ESMTPSA id\n\tr1-20020a056000014100b002c5534db60bsm12523621wrx.71.2023.03.07.02.30.19\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 07 Mar 2023 02:30:19 -0800 (PST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1678185022;\n\tbh=uHukBppQ9A5OsTHDeu/tfXJdWD3XkC4RKes4mVrlEV4=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=q4gvgt+6S6j+q2Xc1LaTnEr7VrijStqCSherdLGcTlLTdpBKFJORWskvDF9g6+zDs\n\tWIoK6EdDHgz2yuDAXILHeno5FEtjI1+/QuB8fbuzQwDV/y98c8xTtYSRrKWmav9KEf\n\tsun9FJ4jrjqVwHjog1ehu4KZs86GYT5gaFNrrjmwMUxXB2u3Sws0eLSA1U4RtMAEAv\n\tG3yuZfcpOk33BEVoKa6RiUXHnFdv1h0J5j+3z7pmT+T2HMdnjxNgnPotOumrUN0brj\n\t4vpmLC/lEj2IDROhyOjAhcxFPQ2pY8Gm+u2XxpNAkV2+Y4smDkYSp9R/xap62jGAER\n\tdiDOdRGfE5i5w==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1678185020;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=PhGw19Z6wfbl/Zl2QWmnDP+EBngZ5SCr/PEqqFZIILA=;\n\tb=Oc9fJCg9ZPDZuSAhHHHpSNC+hvh+yNyQQy1zfBqZUszNQR3QYNKZ+TFN3Jnv4AhiJr\n\tZaPy5gp4WH4nzrOQrNPdZvV2UPyFTiZp1jPOAiBua2vBg3eHqPROehoxWuufO2u2B1Gs\n\tvkPNLsHdIbF0dMyCgEVU1r+t7J5sVUhDiGLCAmL7dTr3J+b8fwPrmZmJNM97X6P4l20P\n\td6lDvPV5Ii/9Z1+8TOIVjKs2Ypb2Xg0eFsTvEckNY8VWPcOGsyb3BvaPh6Qcf++bwqcU\n\tNRo/Lw8O9T5LbqYSfU/4Z//EfToZu7/I6yzWXfmLtG2/cYEdS+wktmwwdhTqncH+DVAd\n\tj0bw=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"Oc9fJCg9\"; dkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112; t=1678185020;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=PhGw19Z6wfbl/Zl2QWmnDP+EBngZ5SCr/PEqqFZIILA=;\n\tb=NVfHT94pXL9ucif2yJ36fomWBmefgXlMGRLgmwhuFNyeiaNKpHyt1V5/IYUzAVS4kK\n\talp+keYzRrDzz2ESyxb4FqeUCQqDUQZByRzhVVlIwII3hX41vFLCbe1Yildxl24S6RtO\n\tr7tK139W7FjmJdzMThVENupYpOnmtb43eDBZkHR3FF92aD6O8hMEBTamgPhQkY0QamiX\n\t/jzAP6UJN+sx+3n6lEO8p2tvg3VK86piXlTwoYJBhXZ/9hk5lkLiRIzSamRHTwOlXjm5\n\thGjUyev5TZjUu6ZmluLMzhce15JGt2n+Wo7L901+Fr3quvyhgrJXUpIMhf3gAQewqoJ0\n\t4RpA==",
        "X-Gm-Message-State": "AO0yUKXfWX+BL5x8Pd+bx82ZadO43xIl8rLvUduWCdWumJ0I7RojtIVc\n\twcZhKaCEy76SIkNoKBPqi/mp54ercaco0+XtSSsYQw==",
        "X-Google-Smtp-Source": "AK7set/tHWL+WysTpjUHHOQMyfFO1+L4GzQra+l0iQCdm1By4sMfTPofrg85+xjRLrb73df3wZ+E+A==",
        "X-Received": "by 2002:adf:ec04:0:b0:2c7:d56:777b with SMTP id\n\tx4-20020adfec04000000b002c70d56777bmr9192339wrn.64.1678185020210; \n\tTue, 07 Mar 2023 02:30:20 -0800 (PST)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Tue,  7 Mar 2023 10:30:22 +0000",
        "Message-Id": "<20230307103023.3932-3-naush@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20230307103023.3932-1-naush@raspberrypi.com>",
        "References": "<20230307103023.3932-1-naush@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v3 2/3] ipa: raspberrypi: Better\n\theuristics for calculating Unicam timeout",
        "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>",
        "From": "Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Naushir Patuck <naush@raspberrypi.com>",
        "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "The existing mechanism of setting a timeout value simply uses the\nmaximum possible frame length advertised by the sensor mode. This can be\nproblematic when, for example, the IMX477 sensor can use a frame length\nof over 600 seconds. However, for typical usage the frame length will\nnever go over several 100s of milliseconds, making the timeout very\nimpractical.\n\nStore a list of the last 10 frame length values requested by the AGC. On\nstartup, and at the end of every frame, take the maximum frame length\nvalue from this list and return that to the pipeline handler through the\nsetCameraTimeoutValue() signal. This allows the timeout value to better\ntrack the actual sensor usage.\n\nSigned-off-by: Naushir Patuck <naush@raspberrypi.com>\nReviewed-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n src/ipa/raspberrypi/raspberrypi.cpp | 45 +++++++++++++++++++++++++++--\n 1 file changed, 42 insertions(+), 3 deletions(-)",
    "diff": "diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\nindex f6826bf27fe1..1375795568e2 100644\n--- a/src/ipa/raspberrypi/raspberrypi.cpp\n+++ b/src/ipa/raspberrypi/raspberrypi.cpp\n@@ -8,6 +8,7 @@\n #include <algorithm>\n #include <array>\n #include <cstring>\n+#include <deque>\n #include <fcntl.h>\n #include <math.h>\n #include <stdint.h>\n@@ -64,6 +65,9 @@ using utils::Duration;\n /* Number of metadata objects available in the context list. */\n constexpr unsigned int numMetadataContexts = 16;\n \n+/* Number of frame length times to hold in the queue. */\n+constexpr unsigned int FrameLengthsQueueSize = 10;\n+\n /* Configure the sensor with these values initially. */\n constexpr double defaultAnalogueGain = 1.0;\n constexpr Duration defaultExposureTime = 20.0ms;\n@@ -121,7 +125,8 @@ class IPARPi : public IPARPiInterface\n public:\n \tIPARPi()\n \t\t: controller_(), frameCount_(0), checkCount_(0), mistrustCount_(0),\n-\t\t  lastRunTimestamp_(0), lsTable_(nullptr), firstStart_(true)\n+\t\t  lastRunTimestamp_(0), lsTable_(nullptr), firstStart_(true),\n+\t\t  lastTimeout_(0s)\n \t{\n \t}\n \n@@ -155,6 +160,7 @@ private:\n \tvoid fillDeviceStatus(const ControlList &sensorControls, unsigned int ipaContext);\n \tRPiController::StatisticsPtr fillStatistics(bcm2835_isp_stats *stats) const;\n \tvoid processStats(unsigned int bufferId, unsigned int ipaContext);\n+\tvoid setCameraTimeoutValue();\n \tvoid applyFrameDurations(Duration minFrameDuration, Duration maxFrameDuration);\n \tvoid applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls);\n \tvoid applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls);\n@@ -220,6 +226,10 @@ private:\n \n \t/* Maximum gain code for the sensor. */\n \tuint32_t maxSensorGainCode_;\n+\n+\t/* Track the frame length times over FrameLengthsQueueSize frames. */\n+\tstd::deque<Duration> frameLengths_;\n+\tDuration lastTimeout_;\n };\n \n int IPARPi::init(const IPASettings &settings, bool lensPresent, IPAInitResult *result)\n@@ -284,6 +294,11 @@ void IPARPi::start(const ControlList &controls, StartConfig *startConfig)\n \n \tcontroller_.switchMode(mode_, &metadata);\n \n+\t/* Reset the frame lengths queue state. */\n+\tlastTimeout_ = 0s;\n+\tframeLengths_.clear();\n+\tframeLengths_.resize(FrameLengthsQueueSize, 0s);\n+\n \t/* SwitchMode may supply updated exposure/gain values to use. */\n \tAgcStatus agcStatus;\n \tagcStatus.shutterTime = 0.0s;\n@@ -294,6 +309,7 @@ void IPARPi::start(const ControlList &controls, StartConfig *startConfig)\n \t\tControlList ctrls(sensorCtrls_);\n \t\tapplyAGC(&agcStatus, ctrls);\n \t\tstartConfig->controls = std::move(ctrls);\n+\t\tsetCameraTimeoutValue();\n \t}\n \n \t/*\n@@ -340,8 +356,6 @@ void IPARPi::start(const ControlList &controls, StartConfig *startConfig)\n \t}\n \n \tstartConfig->dropFrameCount = dropFrameCount_;\n-\tconst Duration maxSensorFrameDuration = mode_.maxFrameLength * mode_.maxLineLength;\n-\tsetCameraTimeout.emit(maxSensorFrameDuration.get<std::milli>());\n \n \tfirstStart_ = false;\n \tlastRunTimestamp_ = 0;\n@@ -1434,6 +1448,22 @@ void IPARPi::processStats(unsigned int bufferId, unsigned int ipaContext)\n \t\tapplyAGC(&agcStatus, ctrls);\n \n \t\tsetDelayedControls.emit(ctrls, ipaContext);\n+\t\tsetCameraTimeoutValue();\n+\t}\n+}\n+\n+void IPARPi::setCameraTimeoutValue()\n+{\n+\t/*\n+\t * Take the maximum value of the exposure queue as the camera timeout\n+\t * value to pass back to the pipeline handler. Only signal if it has changed\n+\t * from the last set value.\n+\t */\n+\tauto max = std::max_element(frameLengths_.begin(), frameLengths_.end());\n+\n+\tif (*max != lastTimeout_) {\n+\t\tsetCameraTimeout.emit(max->get<std::milli>());\n+\t\tlastTimeout_ = *max;\n \t}\n }\n \n@@ -1522,6 +1552,15 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)\n \t */\n \tif (mode_.minLineLength != mode_.maxLineLength)\n \t\tctrls.set(V4L2_CID_HBLANK, static_cast<int32_t>(hblank));\n+\n+\t/*\n+\t * Store the frame length times in a circular queue, up-to FrameLengthsQueueSize\n+\t * elements. This will be used to advertise a camera timeout value to the\n+\t * pipeline handler.\n+\t */\n+\tframeLengths_.pop_front();\n+\tframeLengths_.push_back(helper_->exposure(vblank + mode_.height,\n+\t\t\t\t\t\t  helper_->hblankToLineLength(hblank)));\n }\n \n void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls)\n",
    "prefixes": [
        "libcamera-devel",
        "v3",
        "2/3"
    ]
}