Show a patch.

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

{
    "id": 16522,
    "url": "https://patchwork.libcamera.org/api/patches/16522/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/16522/",
    "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": "<20220703043704.296872-3-utkarsh02t@gmail.com>",
    "date": "2022-07-03T04:37:03",
    "name": "[libcamera-devel,v4,2/3] qcam: Add a GUI way to use capture script",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "dffa755d34238ce21f42c2a11e2a74907c96f176",
    "submitter": {
        "id": 114,
        "url": "https://patchwork.libcamera.org/api/people/114/?format=api",
        "name": "Utkarsh Tiwari",
        "email": "utkarsh02t@gmail.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/16522/mbox/",
    "series": [
        {
            "id": 3244,
            "url": "https://patchwork.libcamera.org/api/series/3244/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3244",
            "date": "2022-07-03T04:37:01",
            "name": "Introduce capture scripts to qcam",
            "version": 4,
            "mbox": "https://patchwork.libcamera.org/series/3244/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/16522/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/16522/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 DB077BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun,  3 Jul 2022 04:37:18 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 88E3A65655;\n\tSun,  3 Jul 2022 06:37:18 +0200 (CEST)",
            "from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com\n\t[IPv6:2607:f8b0:4864:20::102e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 486E76564A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  3 Jul 2022 06:37:16 +0200 (CEST)",
            "by mail-pj1-x102e.google.com with SMTP id\n\tn16-20020a17090ade9000b001ed15b37424so6459072pjv.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 02 Jul 2022 21:37:16 -0700 (PDT)",
            "from localhost.localdomain\n\t([2406:3003:2005:1c27:2dd0:3b05:f874:d165])\n\tby smtp.gmail.com with ESMTPSA id\n\tme3-20020a17090b17c300b001ec84b0f199sm12122299pjb.1.2022.07.02.21.37.13\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 02 Jul 2022 21:37:14 -0700 (PDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656823038;\n\tbh=X1uq2aHaaMyMUojnYyUvc2Nm3lJtwbIY5pf7TGe+KnU=;\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:\n\tFrom;\n\tb=lcdWO9uW9tMURqwpc0XF8L2FLAove0q8tJjv5hw+5vxHqo7fy7cMMZ+J3BYHaBVCY\n\tDlq35tFqTbR0QNdKY6nGSX5MuBIUBuM/eTObjLLb9s/M4TRpTWNVSrgFZ/V/30TIeO\n\t0uFsdZyFcfvMoUyUQiOBWAEjQAN54QxRzDFVXBw3EWm5K0zrEZKGkdaCSEL67/MlMz\n\t9sg/9tfXp7yPT3MmL9dtqOj3Ue9soNPAAUyoq/WcqgqysN6M0PGpszZWWT/0V9ZudW\n\t/86dfmP0AzzAyRXZ9jKwgp3eu/7ExAT+8AzNt2IbFoRIy97iVBZMc5xRntgb03c/hr\n\tYU9bWUBvoL7Ww==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=d4tP4UbnOJfRrStNi8hJIyptEW8NnX+spcZcVCNLeiA=;\n\tb=Q+pqyfgwEVBvbiitUvslMGG7dm0vVr3vTHq+k3/8y8PIiYgEdCnESseGrYdROMUHMu\n\tbN4MQpl7hlbIRYNv8aaxcKxaOqH1tzAKwZL89gXgkPSUuYiS5tddb/o2WaJqtSLpV+Fu\n\t+0nx1uaVTgDocupxpHGNCqMNLJnjCsvNsMTNp0WWJlFkomV880IdoHBUM6015sf6ZsZ3\n\th2r73gzCnOUBKZ+4miJniSluQ0zr7NLOuxwQrYcQecmr7WObP3YEQ14YM8EW4pJROgMo\n\tdwHm4tQNRCsO2Ur+ITjilppe2bWdb6Yl1cdARHdRSxrLeAl6WW/BnoTJ+hn4hHe4Deci\n\toJgQ=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"Q+pqyfgw\"; dkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\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=d4tP4UbnOJfRrStNi8hJIyptEW8NnX+spcZcVCNLeiA=;\n\tb=nYRkV+js5wRNtZt3IlyPnGp6VLTDO8wNheqs534sdS2bY2q4w47isxRvw2hLHWV4/l\n\txT5xaZO78riKV2vHF3ypJ7SMjCBKMgqV0c81VxPgLuuoHyg1Z8TbqL31WTFw792GGFG8\n\tkJLrTuLr9WNzX+QgEhFH6lB52yz+Nnc2Sg+lq82KUhMkPaOAIuAK6xZ3oRSz2aXMioaj\n\tGHzm8utwMA+5PHe2/Xk/U14L81OxdJ8rZvKY9WKj4kwJ/id3Y2vpZP9wX7Q/k0YLvJbY\n\t0CtQ3SNIo+8ZKFZnsWY0zSMT0sQBkiVGnyk9y21abfGVqTt3GKXmTM9CAiMOLJKFyH5j\n\tPpCQ==",
        "X-Gm-Message-State": "AJIora8h8QTw+FIxjCmErWQGoycyHm3n91NaoKPQy9t+wCiyCzOKjwx3\n\t08SNy5FGz8CXGgFH0yWobmchX25ym/nQ3w==",
        "X-Google-Smtp-Source": "AGRyM1vSzWL5bDVB3V47W6Ju7uqN+pp8LOQuNfoDOjswKUqELg56TwOeDBKBUZw3vIFAW/m+KVLE8A==",
        "X-Received": "by 2002:a17:90b:3b4e:b0:1ed:2236:34f3 with SMTP id\n\tot14-20020a17090b3b4e00b001ed223634f3mr27578524pjb.6.1656823034423; \n\tSat, 02 Jul 2022 21:37:14 -0700 (PDT)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Sun,  3 Jul 2022 12:37:03 +0800",
        "Message-Id": "<20220703043704.296872-3-utkarsh02t@gmail.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220703043704.296872-1-utkarsh02t@gmail.com>",
        "References": "<20220703043704.296872-1-utkarsh02t@gmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use capture\n\tscript",
        "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": "Utkarsh Tiwari via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Utkarsh Tiwari <utkarsh02t@gmail.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Implement an Open Capture Script button which would allow the user\nto open a Capture Script (*.yaml).\nThis button has two states Open and Stop.\n\nOpen state allows user to load a capture script.\nWhen clicked in open state present them with a QFileDialog\nto allow user to select a single file.\n\nStop state stops the execution of the current capture script.\n\nIntroduce a queueCount_ to keep track of the requests queued.\n\nWhen stopping the execution no count is reset and the\ncapture continues as it is.\n\nRequests are queued with any controls the script matching\nthe current queueCount_\n\nSigned-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n src/qcam/assets/feathericons/feathericons.qrc |  2 +\n src/qcam/main_window.cpp                      | 68 +++++++++++++++++++\n src/qcam/main_window.h                        |  6 ++\n src/qcam/meson.build                          |  2 +\n 4 files changed, 78 insertions(+)",
    "diff": "diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc\nindex c5302040..6b08395a 100644\n--- a/src/qcam/assets/feathericons/feathericons.qrc\n+++ b/src/qcam/assets/feathericons/feathericons.qrc\n@@ -3,9 +3,11 @@\n <qresource>\n \t<file>aperture.svg</file>\n \t<file>camera-off.svg</file>\n+\t<file>file.svg</file>\n \t<file>play-circle.svg</file>\n \t<file>save.svg</file>\n \t<file>stop-circle.svg</file>\n \t<file>x-circle.svg</file>\n+\t<file>x-square.svg</file>\n </qresource>\n </RCC>\ndiff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\nindex adeb3181..4fbaeccc 100644\n--- a/src/qcam/main_window.cpp\n+++ b/src/qcam/main_window.cpp\n@@ -20,6 +20,7 @@\n #include <QImage>\n #include <QImageWriter>\n #include <QInputDialog>\n+#include <QMessageBox>\n #include <QMutexLocker>\n #include <QStandardPaths>\n #include <QStringList>\n@@ -232,6 +233,13 @@ int MainWindow::createToolbars()\n \tsaveRaw_ = action;\n #endif\n \n+\t/* Open Script... action. */\n+\taction = toolbar_->addAction(QIcon::fromTheme(\"document-open\",\n+\t\t\t\t\t\t      QIcon(\":file.svg\")),\n+\t\t\t\t     \"Open Capture Script\");\n+\tconnect(action, &QAction::triggered, this, &MainWindow::chooseScript);\n+\tscriptExecAction_ = action;\n+\n \treturn 0;\n }\n \n@@ -255,6 +263,60 @@ void MainWindow::updateTitle()\n \tsetWindowTitle(title_ + \" : \" + QString::number(fps, 'f', 2) + \" fps\");\n }\n \n+/**\n+ * \\brief Load a capture script for handling the capture session.\n+ *\n+ * If already capturing, it would restart the capture.\n+ */\n+void MainWindow::chooseScript()\n+{\n+\tif (script_) {\n+\t\t/*\n+\t\t * This is the second valid press of load script button,\n+\t\t * It indicates stopping, Stop and set button for new script.\n+\t\t */\n+\t\tscript_.reset();\n+\t\tscriptExecAction_->setIcon(QIcon::fromTheme(\"document-open\",\n+\t\t\t\t\t\t\t    QIcon(\":file.svg\")));\n+\t\tscriptExecAction_->setText(\"Open Capture Script\");\n+\t\treturn;\n+\t}\n+\n+\tQString scriptFile = QFileDialog::getOpenFileName(this, \"Open Capture Script\", QDir::currentPath(),\n+\t\t\t\t\t\t\t  \"Capture Script (*.yaml)\");\n+\tif (scriptFile.isEmpty())\n+\t\treturn;\n+\n+\t/*\n+\t * If we are already capturing,\n+\t * stop so we don't have stuck image in viewfinder.\n+\t */\n+\tbool wasCapturing = isCapturing_;\n+\tif (isCapturing_)\n+\t\ttoggleCapture(false);\n+\n+\tscript_ = std::make_unique<CaptureScript>(camera_, scriptFile.toStdString());\n+\tif (!script_->valid()) {\n+\t\tscript_.reset();\n+\t\tQMessageBox::critical(this, \"Invalid Script\",\n+\t\t\t\t\t      \"Couldn't load the capture script\");\n+\t\tif (wasCapturing)\n+\t\t\ttoggleCapture(true);\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * Valid script verified\n+\t * Set the button to indicate stopping availibility.\n+\t */\n+\tscriptExecAction_->setIcon(QIcon(\":x-square.svg\"));\n+\tscriptExecAction_->setText(\"Stop Script execution\");\n+\n+\t/* Start capture again if we were capturing before. */\n+\tif (wasCapturing)\n+\t\ttoggleCapture(true);\n+}\n+\n /* -----------------------------------------------------------------------------\n  * Camera Selection\n  */\n@@ -510,6 +572,7 @@ int MainWindow::startCapture()\n \tpreviousFrames_ = 0;\n \tframesCaptured_ = 0;\n \tlastBufferTime_ = 0;\n+\tqueueCount_ = 0;\n \n \tret = camera_->start();\n \tif (ret) {\n@@ -789,5 +852,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n \n int MainWindow::queueRequest(Request *request)\n {\n+\tif (script_)\n+\t\trequest->controls() = script_->frameControls(queueCount_);\n+\n+\tqueueCount_++;\n+\n \treturn camera_->queueRequest(request);\n }\ndiff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\nindex c3e4b665..2cdf7169 100644\n--- a/src/qcam/main_window.h\n+++ b/src/qcam/main_window.h\n@@ -26,6 +26,7 @@\n #include <libcamera/request.h>\n #include <libcamera/stream.h>\n \n+#include \"../cam/capture_script.h\"\n #include \"../cam/stream_options.h\"\n #include \"viewfinder.h\"\n \n@@ -86,11 +87,14 @@ private:\n \tvoid processHotplug(HotplugEvent *e);\n \tvoid processViewfinder(libcamera::FrameBuffer *buffer);\n \n+\tvoid chooseScript();\n+\n \t/* UI elements */\n \tQToolBar *toolbar_;\n \tQAction *startStopAction_;\n \tQComboBox *cameraCombo_;\n \tQAction *saveRaw_;\n+\tQAction *scriptExecAction_;\n \tViewFinder *viewfinder_;\n \n \tQIcon iconPlay_;\n@@ -124,6 +128,8 @@ private:\n \tQElapsedTimer frameRateInterval_;\n \tuint32_t previousFrames_;\n \tuint32_t framesCaptured_;\n+\tuint32_t queueCount_;\n \n \tstd::vector<std::unique_ptr<libcamera::Request>> requests_;\n+\tstd::unique_ptr<CaptureScript> script_;\n };\ndiff --git a/src/qcam/meson.build b/src/qcam/meson.build\nindex c46f4631..67074252 100644\n--- a/src/qcam/meson.build\n+++ b/src/qcam/meson.build\n@@ -15,6 +15,7 @@ endif\n qcam_enabled = true\n \n qcam_sources = files([\n+    '../cam/capture_script.cpp',\n     '../cam/image.cpp',\n     '../cam/options.cpp',\n     '../cam/stream_options.cpp',\n@@ -37,6 +38,7 @@ qcam_resources = files([\n qcam_deps = [\n     libatomic,\n     libcamera_public,\n+    libyaml,\n     qt5_dep,\n ]\n \n",
    "prefixes": [
        "libcamera-devel",
        "v4",
        "2/3"
    ]
}