Patch Detail
Show a patch.
GET /api/patches/16319/?format=api
{ "id": 16319, "url": "https://patchwork.libcamera.org/api/patches/16319/?format=api", "web_url": "https://patchwork.libcamera.org/patch/16319/", "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": "<20220622131638.79122-3-utkarsh02t@gmail.com>", "date": "2022-06-22T13:16:37", "name": "[libcamera-devel,v2,2/3] qcam: Add a GUI way to use capture script", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "58bcccda2332bffb2feb074b915ab9cc0af93522", "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/16319/mbox/", "series": [ { "id": 3204, "url": "https://patchwork.libcamera.org/api/series/3204/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3204", "date": "2022-06-22T13:16:35", "name": "Introduce capture scripts to qcam", "version": 2, "mbox": "https://patchwork.libcamera.org/series/3204/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/16319/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/16319/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 F3D17BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 22 Jun 2022 13:17:31 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9FD2F6563E;\n\tWed, 22 Jun 2022 15:17:31 +0200 (CEST)", "from mail-pg1-x531.google.com (mail-pg1-x531.google.com\n\t[IPv6:2607:f8b0:4864:20::531])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B165761FB2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jun 2022 15:17:29 +0200 (CEST)", "by mail-pg1-x531.google.com with SMTP id s185so10336186pgs.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jun 2022 06:17:29 -0700 (PDT)", "from localhost.localdomain\n\t([2406:3003:2005:1f6b:fd12:eca1:fe45:bbdb])\n\tby smtp.gmail.com with ESMTPSA id\n\tx82-20020a627c55000000b0052089e1b88esm7124540pfc.192.2022.06.22.06.17.25\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 22 Jun 2022 06:17:27 -0700 (PDT)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1655903851;\n\tbh=/PA8YHABfHDJNX1mLlcQY3k6LKfuswo8x9H9/wnml7o=;\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=jZ+ewN5KHJdY7X0CJd5QxLQIkTyJLnG7bcCPQfvRjYkI7bjA0b14DTnSZmcxRDStP\n\tk4gwWMFpU42PoBdaCqcOdaJmbinPWbxrRVqF6aGqL8keOIzEv0ko2EeA10x+Kg37RK\n\tMbOxw3uVpi77/TjeMC0q0IIsPKVzhwQKCouzIYr0p78l8vrSdxjeZ8WZkOS4tTEqEh\n\tcKicCmAbeUpCllh4C20vS6pMiXSZrgIWreVuMTT9cI7LRQ3nRhAwtuXhr/kOOK6RlB\n\tDNuKCmTMgvmvsQc24d2R/xn+5yAGNoejyEVqQnCFUKCJlV0iDgoUehr4tRcFKwcD0J\n\t2zGOez++0ktgQ==", "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=xkf2q1NPqU5B59rU94nWkF8pe6fEleUpU2eY39SlwBs=;\n\tb=Zn70NR76UTBPuVB+uDivmSblpdpJPaBxLNRc0Q9qo5Qos8I9ATpKohCkB8H8SYqiZP\n\tWykaa7niTrMcLZLaJ8sULkXRDhPR0DsW8HMajKUo5oYdC+mdP4lnW8KWdcV7NqmZ0h6r\n\tSA9XvWg+ZwMTq+OaLlhmpgLZk8Vfwbva5vU54zgQbjZ6YPKlrTENF7IYpNZVQHDyVo2P\n\tvjbHQw5W7tao3pvgG/J1fsKqM/lUBtcekEeqnSekuexrJPp3OLapYmbkHDZMB8IlMvoj\n\t1kk7u3vpe/HKxjJN3PSq1EChDyr8GZ6nfbF+/LEytcbNJuuzYCnZ+4H8Yd1yaSACu/dS\n\taSHg==" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"Zn70NR76\"; 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=xkf2q1NPqU5B59rU94nWkF8pe6fEleUpU2eY39SlwBs=;\n\tb=Vttg2YY58fA0//KEeITr56gFJ0YOBjbiN0MBcfPb6hAjNwPmCu7KNOIpVS9sMuXzgO\n\tVYmxAl8Drxrxgbz9NN8ZSYAHWTQMLQt6u8smiptbtzKvORrgT9L1fGSnRdQEQOKzsqGU\n\tBW+l0Mce0sNUca3ypf2HI/ZTgXKg8vqDItF09AbpKWxPaQeYCl/N2osSQM/1L52u39Do\n\tCCfOoNi0tvjM+UvbzcTPdd85ubDHJ/Yq/Eb72Z7G7p5VKvC0tclLjU7gdOZwYvHPDLk8\n\tWXehNqoIC873qF1G20ocq/re+9VGpy0hqJM1V6zoyfpm+BYxT3osOmFrl/W1WFbc4/JQ\n\tBEVQ==", "X-Gm-Message-State": "AJIora/rMLFTXdMniy0OfQKuSx75Km87xDWNaTjkzGxSnpOX2DH80HWK\n\tTizgc1tjYwS8ATmXnpSTOokvlCXL2Xs=", "X-Google-Smtp-Source": "AGRyM1ulXiEdjqPsJadFOVCJKk5y3wxryc/jBkh/JJR9PWXef64cZtq1pnoMv/K4Us3XsfTOgaIz5g==", "X-Received": "by 2002:a63:8949:0:b0:40d:44d6:423e with SMTP id\n\tv70-20020a638949000000b0040d44d6423emr24782pgd.525.1655903847771; \n\tWed, 22 Jun 2022 06:17:27 -0700 (PDT)", "To": "libcamera-devel@lists.libcamera.org", "Date": "Wed, 22 Jun 2022 21:16:37 +0800", "Message-Id": "<20220622131638.79122-3-utkarsh02t@gmail.com>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20220622131638.79122-1-utkarsh02t@gmail.com>", "References": "<20220622131638.79122-1-utkarsh02t@gmail.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v2 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, this would allow better testing\nas we can stop in between script and observe.\n\nInitialize a Script Parser instance when the user selects\na valid capture script.\n\nAt queueRequest() time if script parser has been initialized,\nthen populate the Request::controls() with it at\nqueueRequest time providing the queueCount_.\n\nThe queueCount_ is incremented after the getting controls from\nthe parser, so the first request is for frame 0.\n\nSigned-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n---\n src/qcam/assets/feathericons/feathericons.qrc | 2 +\n src/qcam/main_window.cpp | 61 +++++++++++++++++++\n src/qcam/main_window.h | 7 +++\n src/qcam/meson.build | 2 +\n 4 files changed, 72 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..29da3947 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,53 @@ 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 (isScriptExecuting_) {\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\tisScriptExecuting_ = false;\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+\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\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+\tisScriptExecuting_ = true;\n+\n+\t/* Restart the capture so we can reset every counter */\n+\tif (isCapturing_) {\n+\t\ttoggleCapture(false);\n+\t\ttoggleCapture(true);\n+\t}\n+}\n+\n /* -----------------------------------------------------------------------------\n * Camera Selection\n */\n@@ -510,6 +565,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 +845,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..58df4e15 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@@ -112,6 +116,7 @@ private:\n \n \t/* Capture state, buffers queue and statistics */\n \tbool isCapturing_;\n+\tbool isScriptExecuting_;\n \tbool captureRaw_;\n \tlibcamera::Stream *vfStream_;\n \tlibcamera::Stream *rawStream_;\n@@ -124,6 +129,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", "v2", "2/3" ] }