[{"id":23720,"web_url":"https://patchwork.libcamera.org/comment/23720/","msgid":"<CAHbe+E388L-nf8QGa6_WyDHtWR0wZ7tkcK6BpEpMJhRusWqw1A@mail.gmail.com>","date":"2022-07-04T15:46:18","subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","submitter":{"id":114,"url":"https://patchwork.libcamera.org/api/people/114/","name":"Utkarsh Tiwari","email":"utkarsh02t@gmail.com"},"content":"On Sun, Jul 3, 2022 at 12:37 PM Utkarsh Tiwari <utkarsh02t@gmail.com> wrote:\n\n> Implement an Open Capture Script button which would allow the user\n> to open a Capture Script (*.yaml).\n> This button has two states Open and Stop.\n>\n> Open state allows user to load a capture script.\n> When clicked in open state present them with a QFileDialog\n> to allow user to select a single file.\n>\n> Stop state stops the execution of the current capture script.\n>\n> Introduce a queueCount_ to keep track of the requests queued.\n>\n> When stopping the execution no count is reset and the\n> capture continues as it is.\n>\n> Requests are queued with any controls the script matching\n> the current queueCount_\n>\n> Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n> Reviewed-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(+)\n>\n> diff --git a/src/qcam/assets/feathericons/feathericons.qrc\n> b/src/qcam/assets/feathericons/feathericons.qrc\n> index 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>         <file>aperture.svg</file>\n>         <file>camera-off.svg</file>\n> +       <file>file.svg</file>\n>         <file>play-circle.svg</file>\n>         <file>save.svg</file>\n>         <file>stop-circle.svg</file>\n>         <file>x-circle.svg</file>\n> +       <file>x-square.svg</file>\n>  </qresource>\n>  </RCC>\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 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>         saveRaw_ = action;\n>  #endif\n>\n> +       /* Open Script... action. */\n> +       action = toolbar_->addAction(QIcon::fromTheme(\"document-open\",\n> +                                                     QIcon(\":file.svg\")),\n> +                                    \"Open Capture Script\");\n> +       connect(action, &QAction::triggered, this,\n> &MainWindow::chooseScript);\n> +       scriptExecAction_ = action;\n> +\n>         return 0;\n>  }\n>\n> @@ -255,6 +263,60 @@ void MainWindow::updateTitle()\n>         setWindowTitle(title_ + \" : \" + QString::number(fps, 'f', 2) + \"\n> 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> +       if (script_) {\n> +               /*\n> +                * This is the second valid press of load script button,\n> +                * It indicates stopping, Stop and set button for new\n> script.\n> +                */\n> +               script_.reset();\n> +\n>  scriptExecAction_->setIcon(QIcon::fromTheme(\"document-open\",\n> +\n>  QIcon(\":file.svg\")));\n> +               scriptExecAction_->setText(\"Open Capture Script\");\n> +               return;\n> +       }\n> +\n> +       QString scriptFile = QFileDialog::getOpenFileName(this, \"Open\n> Capture Script\", QDir::currentPath(),\n> +                                                         \"Capture Script\n> (*.yaml)\");\n> +       if (scriptFile.isEmpty())\n> +               return;\n> +\n> +       /*\n> +        * If we are already capturing,\n> +        * stop so we don't have stuck image in viewfinder.\n> +        */\n> +       bool wasCapturing = isCapturing_;\n> +       if (isCapturing_)\n> +               toggleCapture(false);\n> +\n> +       script_ = std::make_unique<CaptureScript>(camera_,\n> scriptFile.toStdString());\n> +       if (!script_->valid()) {\n> +               script_.reset();\n> +               QMessageBox::critical(this, \"Invalid Script\",\n> +                                             \"Couldn't load the capture\n> script\");\n>\n\nThis is wrongly indented  and should be\n\n\t\tQMessageBox::critical(this, \"Invalid Script\",\n\t\t\t\t      \"Couldn't load the capture script\");\n\n+               if (wasCapturing)\n> +                       toggleCapture(true);\n> +               return;\n> +       }\n> +\n> +       /*\n> +        * Valid script verified\n> +        * Set the button to indicate stopping availibility.\n> +        */\n> +       scriptExecAction_->setIcon(QIcon(\":x-square.svg\"));\n> +       scriptExecAction_->setText(\"Stop Script execution\");\n> +\n> +       /* Start capture again if we were capturing before. */\n> +       if (wasCapturing)\n> +               toggleCapture(true);\n> +}\n> +\n>  /*\n> -----------------------------------------------------------------------------\n>   * Camera Selection\n>   */\n> @@ -510,6 +572,7 @@ int MainWindow::startCapture()\n>         previousFrames_ = 0;\n>         framesCaptured_ = 0;\n>         lastBufferTime_ = 0;\n> +       queueCount_ = 0;\n>\n>         ret = camera_->start();\n>         if (ret) {\n> @@ -789,5 +852,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n>\n>  int MainWindow::queueRequest(Request *request)\n>  {\n> +       if (script_)\n> +               request->controls() = script_->frameControls(queueCount_);\n> +\n> +       queueCount_++;\n> +\n>         return camera_->queueRequest(request);\n>  }\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index 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>         void processHotplug(HotplugEvent *e);\n>         void processViewfinder(libcamera::FrameBuffer *buffer);\n>\n> +       void chooseScript();\n> +\n>         /* UI elements */\n>         QToolBar *toolbar_;\n>         QAction *startStopAction_;\n>         QComboBox *cameraCombo_;\n>         QAction *saveRaw_;\n> +       QAction *scriptExecAction_;\n>         ViewFinder *viewfinder_;\n>\n>         QIcon iconPlay_;\n> @@ -124,6 +128,8 @@ private:\n>         QElapsedTimer frameRateInterval_;\n>         uint32_t previousFrames_;\n>         uint32_t framesCaptured_;\n> +       uint32_t queueCount_;\n>\n>         std::vector<std::unique_ptr<libcamera::Request>> requests_;\n> +       std::unique_ptr<CaptureScript> script_;\n>  };\n> diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n> index 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> --\n> 2.25.1\n>\n>","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 3DA1EBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  4 Jul 2022 15:46:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7ABEF6564E;\n\tMon,  4 Jul 2022 17:46:33 +0200 (CEST)","from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com\n\t[IPv6:2607:f8b0:4864:20::62e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CBBA361FB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  4 Jul 2022 17:46:31 +0200 (CEST)","by mail-pl1-x62e.google.com with SMTP id c13so5118654pla.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 04 Jul 2022 08:46:31 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656949593;\n\tbh=NJIZ6/XuI1UZeAgT4kt4sX8uzk0T9v1SszxjJ9WLy0k=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=QioBVFi+ldEFZ8y6vEXCMalyzksVGQ7OlE7ww8gamRjywnkxNGThIxUmvdiEdAsXI\n\tRXMSRXTSIHS2FCfBYpKMBROAN+V8I3z84dUJG8Kc0GU365eMbS14QKAsS1JC3ErVc0\n\tBBn1TbNI/YI8AFU3pZXAW3WXV2+g9lhBQWjQ+EWAG3IwDXI0Nto3XIuIv5XBXykc22\n\tiyZwN2AEzWdUZQ90LYHjYl93Z4mv6s1xGdqTDyxieoq3c7lYIS05arXHAQa/Zrt2a+\n\t+y64SB0+ycMp6bWjgk7265vS98KUcvu05qZdlXKgOkFLueibyY9BYW48CWEzPKDX5L\n\t4326sOj7WTaJQ==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=DVRoqXSd0aKk+xxEaUWb/yuyDHTZfa34ZuowGPyms2o=;\n\tb=kT9D/sLXfeO2rcFvFpQaYizV0dJAK0QK7Qh1L+LoJnhbE+wNTCs7fMvHWqyU6A4t/j\n\tlfVzJrN94f8qni7RUIbKtLcGxkdAfZVI0xz+VGOPSdYvVDTbTeJz4/Pf219QLXwDNkGm\n\tGno00rKiVw8dy7YM7O14elLTzEcA3l+YfEXAPzAkQ0hZz6hu3YpPVtU0p0Otn+kbeIt9\n\toEfd+zeV1turBvOvJgkVou4MxXctvKtBbByrURY1GK2R+d76KlPh3hxHFbeZJ/kxm3iF\n\tXGXqK8jIm8JmdFDvaCT2OnVOEw088pvGbRBDg3tBFV+lGtTSHwq1gWjJU6VpovWICISC\n\toSTg=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"kT9D/sLX\"; 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:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=DVRoqXSd0aKk+xxEaUWb/yuyDHTZfa34ZuowGPyms2o=;\n\tb=vtU8cslCuAhR0y7h+M/AzTG4/omck9XnH1E8iwDRDkyMn9lKG2N7gUCLkXOzfUERp9\n\t2lhBzWQJHwr+PnTI7osb5LJLuZwmPRi+lEyUJarOytHKWl4FOJPf44xVp89c55VTQWFF\n\tidh22B91I/vbdamzHcXlgPgZ8LoWCsLa0UHZ/X4kwrRwTQHbrvSz5RuHmZWlr3tRqDSz\n\tB+9nUy6zfwqtfHdMNuL+MGw4dju6W5D0LCWqc9+WHj+1V5dxdbT3Bw9AA1J9UAwAcCLu\n\tUuBaI4x+cRJhBIbaSzipjcxFPquiUClMqoNzufkgCgKQib/BloGh0LdXA1Jd5w54eSwO\n\tl1xg==","X-Gm-Message-State":"AJIora+qa7U3i4/7xuiXYZPbxuwvEeSrWhQautpsr5Qb3hf5/QMAFajD\n\tD3/aOoQ3preUhVnP+v4HYIC7ZQGYZ8wvWNnYC1YT6CV555KSeQ==","X-Google-Smtp-Source":"AGRyM1sw+LwzSL3nxfDK4Bph1SGDsC4XnK1KksM0APZdlacBK547i0RcmZE/31SMHgJODNLv3I/TLM53RrWSmRyVNIY=","X-Received":"by 2002:a17:90b:17cb:b0:1ec:9d52:46f7 with SMTP id\n\tme11-20020a17090b17cb00b001ec9d5246f7mr35338939pjb.221.1656949589928;\n\tMon, 04 Jul 2022 08:46:29 -0700 (PDT)","MIME-Version":"1.0","References":"<20220703043704.296872-1-utkarsh02t@gmail.com>\n\t<20220703043704.296872-3-utkarsh02t@gmail.com>","In-Reply-To":"<20220703043704.296872-3-utkarsh02t@gmail.com>","Date":"Mon, 4 Jul 2022 23:46:18 +0800","Message-ID":"<CAHbe+E388L-nf8QGa6_WyDHtWR0wZ7tkcK6BpEpMJhRusWqw1A@mail.gmail.com>","To":"libcamera-devel@lists.libcamera.org","Content-Type":"multipart/alternative; boundary=\"000000000000b7efd105e2fca385\"","Subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","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>"}},{"id":24116,"web_url":"https://patchwork.libcamera.org/comment/24116/","msgid":"<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>","date":"2022-07-25T18:44:15","subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Utkarsh,\n\nOn 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote:\n> Implement an Open Capture Script button which would allow the user\n> to open a Capture Script (*.yaml).\n> This button has two states Open and Stop.\n>\n> Open state allows user to load a capture script.\n> When clicked in open state present them with a QFileDialog\n> to allow user to select a single file.\n>\n> Stop state stops the execution of the current capture script.\n>\n> Introduce a queueCount_ to keep track of the requests queued.\n>\n> When stopping the execution no count is reset and the\n> capture continues as it is.\n\n\nSo there are two states of stop(s) ? One would stop the capture script \nand other one would stop the camera? Is my understanding correct?\n\n>\n> Requests are queued with any controls the script matching\n> the current queueCount_\n>\n> Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n> Reviewed-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(+)\n>\n> diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc\n> index 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>\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 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>   }\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index 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>   };\n> diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n> index 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>","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 444DAC3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 25 Jul 2022 18:44:22 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A593A63312;\n\tMon, 25 Jul 2022 20:44:21 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1893A6330A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 25 Jul 2022 20:44:21 +0200 (CEST)","from [IPV6:2401:4900:1f3e:f7a:bc8f:12ed:b45f:c35d] (unknown\n\t[IPv6:2401:4900:1f3e:f7a:bc8f:12ed:b45f:c35d])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F0FE76D1;\n\tMon, 25 Jul 2022 20:44:19 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658774661;\n\tbh=wvFFDrcoZ7gY9/NGCVo2SzbAoa91ezF106AbmUJkg5E=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=KObDfaKLKRmeHFBgh3CI1QsD0Mz01N9R2WzlVQt9WfoVmJ5q2jmZOxK8LcyQJe4Un\n\trwafTiCtphVKf5LAMgnFP7phcaOoISX31PNboR6DAIHBlsItsVnIJJKCYviI1RWdlt\n\tOI6ZFbqCKdROBo5KxiiR7p0E6w63S6sbtZGPc32D9p/fqlMm92bhaund7cNNlZJaeh\n\tJOJR6hw0PXXCfxioaebpxMdJjOKTccYXOx2RFbFhQWk8iegC49V/rN4ySq7c+pll7R\n\tL2NJjuCa6+mCtit2bv8uryhLhMqS3+m0j7o0spk8hwg3gxIC25UOQ6dDNpTwOWJ2Xd\n\t599x5JtZcQUuw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1658774660;\n\tbh=wvFFDrcoZ7gY9/NGCVo2SzbAoa91ezF106AbmUJkg5E=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=QnoIlzJElpPZk22V1p7hHyGgTqo6SbZn0Tegq0rVbpNyTGYTH0oouem0/OjG9PEye\n\tfosfS49/wzilwjRK+G0A/9v8kRcWJaTjsMAH4zLrp97sfHvZITm2UMWVAVD9E+NkFK\n\tZC2brSsa9U2XQdbCURAGNhT8+UKZvWVT24bk4QI0="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"QnoIlzJE\"; dkim-atps=neutral","Message-ID":"<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>","Date":"Tue, 26 Jul 2022 00:14:15 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.4.1","Content-Language":"en-US","To":"Utkarsh Tiwari <utkarsh02t@gmail.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20220703043704.296872-1-utkarsh02t@gmail.com>\n\t<20220703043704.296872-3-utkarsh02t@gmail.com>","In-Reply-To":"<20220703043704.296872-3-utkarsh02t@gmail.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","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":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":24135,"web_url":"https://patchwork.libcamera.org/comment/24135/","msgid":"<CAHbe+E1jkZ5CcWaFBsp2T5cnh3CtZOFEVsOJOT6+TQY3F9Sfmg@mail.gmail.com>","date":"2022-07-26T02:20:14","subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","submitter":{"id":114,"url":"https://patchwork.libcamera.org/api/people/114/","name":"Utkarsh Tiwari","email":"utkarsh02t@gmail.com"},"content":"On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote:\n\n> Hi Utkarsh,\n>\n> On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote:\n> > Implement an Open Capture Script button which would allow the user\n> > to open a Capture Script (*.yaml).\n> > This button has two states Open and Stop.\n> >\n> > Open state allows user to load a capture script.\n> > When clicked in open state present them with a QFileDialog\n> > to allow user to select a single file.\n> >\n> > Stop state stops the execution of the current capture script.\n> >\n> > Introduce a queueCount_ to keep track of the requests queued.\n> >\n> > When stopping the execution no count is reset and the\n> > capture continues as it is.\n>\n>\n> So there are two states of stop(s) ? One would stop the capture script\n> and other one would stop the camera? Is my understanding correct?\n>\n\nNo, the two states of the button are\n- Open Capture Script\n- Stop the current capture script\n\nThe  open state allows the user to select a capture script to execute.\n\nThe stop state is visible when the user has loaded a capture script either\nthrough cmdline  or through the button. This state allows to stop the\ncurrent script.\n\nShould reword the commit message ?\n\n>\n>\n> >\n> > Requests are queued with any controls the script matching\n> > the current queueCount_\n> >\n> > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n> > Reviewed-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(+)\n> >\n> > diff --git a/src/qcam/assets/feathericons/feathericons.qrc\n> b/src/qcam/assets/feathericons/feathericons.qrc\n> > index 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> >       <file>aperture.svg</file>\n> >       <file>camera-off.svg</file>\n> > +     <file>file.svg</file>\n> >       <file>play-circle.svg</file>\n> >       <file>save.svg</file>\n> >       <file>stop-circle.svg</file>\n> >       <file>x-circle.svg</file>\n> > +     <file>x-square.svg</file>\n> >   </qresource>\n> >   </RCC>\n> > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > index 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> >       saveRaw_ = action;\n> >   #endif\n> >\n> > +     /* Open Script... action. */\n> > +     action = toolbar_->addAction(QIcon::fromTheme(\"document-open\",\n> > +                                                   QIcon(\":file.svg\")),\n> > +                                  \"Open Capture Script\");\n> > +     connect(action, &QAction::triggered, this,\n> &MainWindow::chooseScript);\n> > +     scriptExecAction_ = action;\n> > +\n> >       return 0;\n> >   }\n> >\n> > @@ -255,6 +263,60 @@ void MainWindow::updateTitle()\n> >       setWindowTitle(title_ + \" : \" + QString::number(fps, 'f', 2) + \"\n> 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> > +     if (script_) {\n> > +             /*\n> > +              * This is the second valid press of load script button,\n> > +              * It indicates stopping, Stop and set button for new\n> script.\n> > +              */\n> > +             script_.reset();\n> > +\n>  scriptExecAction_->setIcon(QIcon::fromTheme(\"document-open\",\n> > +\n>  QIcon(\":file.svg\")));\n> > +             scriptExecAction_->setText(\"Open Capture Script\");\n> > +             return;\n> > +     }\n> > +\n> > +     QString scriptFile = QFileDialog::getOpenFileName(this, \"Open\n> Capture Script\", QDir::currentPath(),\n> > +                                                       \"Capture Script\n> (*.yaml)\");\n> > +     if (scriptFile.isEmpty())\n> > +             return;\n> > +\n> > +     /*\n> > +      * If we are already capturing,\n> > +      * stop so we don't have stuck image in viewfinder.\n> > +      */\n> > +     bool wasCapturing = isCapturing_;\n> > +     if (isCapturing_)\n> > +             toggleCapture(false);\n> > +\n> > +     script_ = std::make_unique<CaptureScript>(camera_,\n> scriptFile.toStdString());\n> > +     if (!script_->valid()) {\n> > +             script_.reset();\n> > +             QMessageBox::critical(this, \"Invalid Script\",\n> > +                                           \"Couldn't load the capture\n> script\");\n> > +             if (wasCapturing)\n> > +                     toggleCapture(true);\n> > +             return;\n> > +     }\n> > +\n> > +     /*\n> > +      * Valid script verified\n> > +      * Set the button to indicate stopping availibility.\n> > +      */\n> > +     scriptExecAction_->setIcon(QIcon(\":x-square.svg\"));\n> > +     scriptExecAction_->setText(\"Stop Script execution\");\n> > +\n> > +     /* Start capture again if we were capturing before. */\n> > +     if (wasCapturing)\n> > +             toggleCapture(true);\n> > +}\n> > +\n> >   /*\n> -----------------------------------------------------------------------------\n> >    * Camera Selection\n> >    */\n> > @@ -510,6 +572,7 @@ int MainWindow::startCapture()\n> >       previousFrames_ = 0;\n> >       framesCaptured_ = 0;\n> >       lastBufferTime_ = 0;\n> > +     queueCount_ = 0;\n> >\n> >       ret = camera_->start();\n> >       if (ret) {\n> > @@ -789,5 +852,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n> >\n> >   int MainWindow::queueRequest(Request *request)\n> >   {\n> > +     if (script_)\n> > +             request->controls() = script_->frameControls(queueCount_);\n> > +\n> > +     queueCount_++;\n> > +\n> >       return camera_->queueRequest(request);\n> >   }\n> > diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> > index 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> >       void processHotplug(HotplugEvent *e);\n> >       void processViewfinder(libcamera::FrameBuffer *buffer);\n> >\n> > +     void chooseScript();\n> > +\n> >       /* UI elements */\n> >       QToolBar *toolbar_;\n> >       QAction *startStopAction_;\n> >       QComboBox *cameraCombo_;\n> >       QAction *saveRaw_;\n> > +     QAction *scriptExecAction_;\n> >       ViewFinder *viewfinder_;\n> >\n> >       QIcon iconPlay_;\n> > @@ -124,6 +128,8 @@ private:\n> >       QElapsedTimer frameRateInterval_;\n> >       uint32_t previousFrames_;\n> >       uint32_t framesCaptured_;\n> > +     uint32_t queueCount_;\n> >\n> >       std::vector<std::unique_ptr<libcamera::Request>> requests_;\n> > +     std::unique_ptr<CaptureScript> script_;\n> >   };\n> > diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n> > index 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>","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 0E925C3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Jul 2022 02:20:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0458163312;\n\tTue, 26 Jul 2022 04:20:31 +0200 (CEST)","from mail-pl1-x635.google.com (mail-pl1-x635.google.com\n\t[IPv6:2607:f8b0:4864:20::635])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 47141603E9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Jul 2022 04:20:29 +0200 (CEST)","by mail-pl1-x635.google.com with SMTP id d3so4186087pls.4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 25 Jul 2022 19:20:29 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658802031;\n\tbh=8W2dX+d3PtXWyExw5KblZMptNeJqMtUC9+yA1ffLmis=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=MuxVEKKUmlEZBCDHeajPr3oDQm8ccxi+O4AifAimMLLkOW139vJ7fINlQ7dFjJXZJ\n\tLYwGiL82mDG7SYYq677WMyeY6KsA19mlDv5DAFxhXcBJps5D2xf5cofQMg+hC+7j9S\n\t4ExSnE/AxxkcZ50bf8eLKH5p79p4o+gRkKomnnDpkwZ0pi6UJUlaUKI3Emj5dLDyPO\n\t2C0XqLRdYLODWS4tDfOPzM0Xbi44mTeK331kiYOs8sqq/K79bZJAz8aeE4anLWPADn\n\t7eUnCN1BRBvzE9lXLxMjSDCW1rP7mhZodyhSF+WvJx69lXoQgxu6rsI9yPsxsmLMTB\n\top7FX171j0d8Q==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=QRr/I06O0hhY5rbMyzrBoSwByCv+P8umIwfXwqrXYBg=;\n\tb=oEmb+qvODPgyVMcWDQRUx8pl+XCw0vrz3e9OkrgnkKZSyFuH0AvZMm2pKViNJand5s\n\tqSkOIESxXtPMmd9k8mQBHkDX4jPdVLv7wy9BstHyO3RAFMPR5pCqjNBVMwhMQWA4uk68\n\tcf6ydyqXo3roTQrSNvxdd02eRLYuE+uV5AXtV/8MYmNWxv3RUyM0jDvoThIe6T/YOp7m\n\tU9UVwwz/E03kklvN6WxM0R6xYKFImyD+p1Cmhz+zUG/P0I+H2JS+JwE3Gi+zI/SwJLZS\n\txmPZqDUTrJ7VIIwT4++dSVW/9BoBJ5/uAEezbs7sv6Ep+K1wIko/V0UZOPfS77M3+TSC\n\tnH/w=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"oEmb+qvO\"; 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:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=QRr/I06O0hhY5rbMyzrBoSwByCv+P8umIwfXwqrXYBg=;\n\tb=DD9I49j8nRc9aLWaAbeBReHzXJ0v8FxQFYrAUAPjkWIyDTC/1zJwRJozoGYaRsOaoA\n\tinkSLxfZD1RuQD0mViPfg6ynvtKC16WQqRwCLYyCz5ZGIoATDfQ5ADYpfukkIiwHmIaw\n\tPGpON9LT5rDJKiFiRMxJngZAdaGWJk3vh+HjODspl3ELa/Fi4HooDYt97F86ykPp6Yo3\n\t6WQ+crvDmoourqTQfRZIo4SniQZP+A+uIkhvvDx0Fnp4V9LaGnSyJn1t0D8ZB0Y/o/aB\n\tZHGS1yEp+tNbmhawUJ1xYl+zq/gQYZurdwweRWy0av8XzLMxm65rR0+NmLpDIikxs7AN\n\t7FQw==","X-Gm-Message-State":"AJIora/AXG1TLS/4UzGzjZMzwb8sXixVaDD99hIo3b963CAEaRXx5OrT\n\tbob4Tf7fEY93DqXgW4e/n1EQ9RAM3ik436Mr50NQ6IdE","X-Google-Smtp-Source":"AGRyM1uC5cwrpgZrsCjUK6oG2doBcW16lpjfdDQ/EAf82WNdQqiOPl0n6vVzKN6x9XWsZqBZaiTaY62w+x18gde9TsQ=","X-Received":"by 2002:a17:90b:17c9:b0:1f2:ab2f:25a4 with SMTP id\n\tme9-20020a17090b17c900b001f2ab2f25a4mr9332518pjb.221.1658802027250;\n\tMon, 25 Jul 2022 19:20:27 -0700 (PDT)","MIME-Version":"1.0","References":"<20220703043704.296872-1-utkarsh02t@gmail.com>\n\t<20220703043704.296872-3-utkarsh02t@gmail.com>\n\t<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>","In-Reply-To":"<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>","Date":"Tue, 26 Jul 2022 07:50:14 +0530","Message-ID":"<CAHbe+E1jkZ5CcWaFBsp2T5cnh3CtZOFEVsOJOT6+TQY3F9Sfmg@mail.gmail.com>","To":"Umang Jain <umang.jain@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"00000000000096489d05e4abf1c3\"","Subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":24137,"web_url":"https://patchwork.libcamera.org/comment/24137/","msgid":"<21627efc-f53a-a3bd-04dc-5046df3cf158@ideasonboard.com>","date":"2022-07-26T05:07:36","subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Utkarsh,\n\nOn 7/26/22 07:50, Utkarsh Tiwari wrote:\n> On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote:\n>\n>> Hi Utkarsh,\n>>\n>> On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote:\n>>> Implement an Open Capture Script button which would allow the user\n>>> to open a Capture Script (*.yaml).\n>>> This button has two states Open and Stop.\n>>>\n>>> Open state allows user to load a capture script.\n>>> When clicked in open state present them with a QFileDialog\n>>> to allow user to select a single file.\n>>>\n>>> Stop state stops the execution of the current capture script.\n>>>\n>>> Introduce a queueCount_ to keep track of the requests queued.\n>>>\n>>> When stopping the execution no count is reset and the\n>>> capture continues as it is.\n>>\n>> So there are two states of stop(s) ? One would stop the capture script\n>> and other one would stop the camera? Is my understanding correct?\n>>\n> No, the two states of the button are\n> - Open Capture Script\n> - Stop the current capture script\n>\n> The  open state allows the user to select a capture script to execute.\n>\n> The stop state is visible when the user has loaded a capture script either\n> through cmdline  or through the button. This state allows to stop the\n> current script.\n>\n> Should reword the commit message ?\n\nYes, it would be helpful.\n\nEspecially this bit:\n\n     When stopping the execution no count is reset and the\n     capture continues as it is.\n\nI also want to ask that we had a recent change where request sequence number\nare reset to zero on every start()/stop() cycles. So is this a concern \nthis patchset or capture script in general?\n\nhttps://git.libcamera.org/libcamera/libcamera.git/commit/?id=458d917\n\n>>\n>>> Requests are queued with any controls the script matching\n>>> the current queueCount_\n>>>\n>>> Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n>>> Reviewed-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(+)\n>>>\n>>> diff --git a/src/qcam/assets/feathericons/feathericons.qrc\n>> b/src/qcam/assets/feathericons/feathericons.qrc\n>>> index 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>>>        <file>aperture.svg</file>\n>>>        <file>camera-off.svg</file>\n>>> +     <file>file.svg</file>\n>>>        <file>play-circle.svg</file>\n>>>        <file>save.svg</file>\n>>>        <file>stop-circle.svg</file>\n>>>        <file>x-circle.svg</file>\n>>> +     <file>x-square.svg</file>\n>>>    </qresource>\n>>>    </RCC>\n>>> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n>>> index 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>>>        saveRaw_ = action;\n>>>    #endif\n>>>\n>>> +     /* Open Script... action. */\n>>> +     action = toolbar_->addAction(QIcon::fromTheme(\"document-open\",\n>>> +                                                   QIcon(\":file.svg\")),\n>>> +                                  \"Open Capture Script\");\n>>> +     connect(action, &QAction::triggered, this,\n>> &MainWindow::chooseScript);\n>>> +     scriptExecAction_ = action;\n>>> +\n>>>        return 0;\n>>>    }\n>>>\n>>> @@ -255,6 +263,60 @@ void MainWindow::updateTitle()\n>>>        setWindowTitle(title_ + \" : \" + QString::number(fps, 'f', 2) + \"\n>> 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>>> +     if (script_) {\n>>> +             /*\n>>> +              * This is the second valid press of load script button,\n>>> +              * It indicates stopping, Stop and set button for new\n>> script.\n>>> +              */\n>>> +             script_.reset();\n>>> +\n>>   scriptExecAction_->setIcon(QIcon::fromTheme(\"document-open\",\n>>> +\n>>   QIcon(\":file.svg\")));\n>>> +             scriptExecAction_->setText(\"Open Capture Script\");\n>>> +             return;\n>>> +     }\n>>> +\n>>> +     QString scriptFile = QFileDialog::getOpenFileName(this, \"Open\n>> Capture Script\", QDir::currentPath(),\n>>> +                                                       \"Capture Script\n>> (*.yaml)\");\n>>> +     if (scriptFile.isEmpty())\n>>> +             return;\n>>> +\n>>> +     /*\n>>> +      * If we are already capturing,\n>>> +      * stop so we don't have stuck image in viewfinder.\n>>> +      */\n>>> +     bool wasCapturing = isCapturing_;\n>>> +     if (isCapturing_)\n>>> +             toggleCapture(false);\n>>> +\n>>> +     script_ = std::make_unique<CaptureScript>(camera_,\n>> scriptFile.toStdString());\n>>> +     if (!script_->valid()) {\n>>> +             script_.reset();\n>>> +             QMessageBox::critical(this, \"Invalid Script\",\n>>> +                                           \"Couldn't load the capture\n>> script\");\n>>> +             if (wasCapturing)\n>>> +                     toggleCapture(true);\n>>> +             return;\n>>> +     }\n>>> +\n>>> +     /*\n>>> +      * Valid script verified\n>>> +      * Set the button to indicate stopping availibility.\n>>> +      */\n>>> +     scriptExecAction_->setIcon(QIcon(\":x-square.svg\"));\n>>> +     scriptExecAction_->setText(\"Stop Script execution\");\n>>> +\n>>> +     /* Start capture again if we were capturing before. */\n>>> +     if (wasCapturing)\n>>> +             toggleCapture(true);\n>>> +}\n>>> +\n>>>    /*\n>> -----------------------------------------------------------------------------\n>>>     * Camera Selection\n>>>     */\n>>> @@ -510,6 +572,7 @@ int MainWindow::startCapture()\n>>>        previousFrames_ = 0;\n>>>        framesCaptured_ = 0;\n>>>        lastBufferTime_ = 0;\n>>> +     queueCount_ = 0;\n>>>\n>>>        ret = camera_->start();\n>>>        if (ret) {\n>>> @@ -789,5 +852,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n>>>\n>>>    int MainWindow::queueRequest(Request *request)\n>>>    {\n>>> +     if (script_)\n>>> +             request->controls() = script_->frameControls(queueCount_);\n>>> +\n>>> +     queueCount_++;\n>>> +\n>>>        return camera_->queueRequest(request);\n>>>    }\n>>> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n>>> index 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>>>        void processHotplug(HotplugEvent *e);\n>>>        void processViewfinder(libcamera::FrameBuffer *buffer);\n>>>\n>>> +     void chooseScript();\n>>> +\n>>>        /* UI elements */\n>>>        QToolBar *toolbar_;\n>>>        QAction *startStopAction_;\n>>>        QComboBox *cameraCombo_;\n>>>        QAction *saveRaw_;\n>>> +     QAction *scriptExecAction_;\n>>>        ViewFinder *viewfinder_;\n>>>\n>>>        QIcon iconPlay_;\n>>> @@ -124,6 +128,8 @@ private:\n>>>        QElapsedTimer frameRateInterval_;\n>>>        uint32_t previousFrames_;\n>>>        uint32_t framesCaptured_;\n>>> +     uint32_t queueCount_;\n>>>\n>>>        std::vector<std::unique_ptr<libcamera::Request>> requests_;\n>>> +     std::unique_ptr<CaptureScript> script_;\n>>>    };\n>>> diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n>>> index 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>>>","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 658AAC3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Jul 2022 05:07:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A44E063312;\n\tTue, 26 Jul 2022 07:07:43 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BFD0C603E9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Jul 2022 07:07:41 +0200 (CEST)","from [IPV6:2401:4900:1f3e:f7a:bc8f:12ed:b45f:c35d] (unknown\n\t[IPv6:2401:4900:1f3e:f7a:bc8f:12ed:b45f:c35d])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C1F9A735;\n\tTue, 26 Jul 2022 07:07:40 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658812063;\n\tbh=mdVEsQI130gVZRwf7uG3Grr5YfLapR6MikVWNzgI5uE=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=r1OFFx45fwSjqSdZA+cADRiGGlqA4mASVvw9fSgXg+M9/YzJT2ch+xLm0UXe0AlKp\n\t6cLq+enQ433cF5BJRJg4DV8Q+vQ+gON8xUEI0QPBK7RtIm8a6RTkHNS9hJAzXVtS3Q\n\tGmWD0vBk8cl1I7H8Jvu6/D834sSnCCrzLDAJAsl4sdUGbIo8IrrCmU6gVRUO5d80Ja\n\tbxjDNvgxDzFxmJq9jyOmbP6mw2TmLnYUJM9tYfjQJPwH5bMJ2f6iqfgCKaKNYACc3f\n\tvxrAnv5G3/eQ1YTXl1dWUsYn+ZstHtkWjc95Pdh7/YpbeesywIVBxkPtQzMETgXQFr\n\tjKXk0EPPDISBA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1658812061;\n\tbh=mdVEsQI130gVZRwf7uG3Grr5YfLapR6MikVWNzgI5uE=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=m97RPA7uGaMKO5pshDPcyNsKEZS6LN9T6UVfiyvb9du3qiMSr9KEIwWwTAhXJhPSa\n\t/fgfYSIGRk2DbfGYrSL/sgIuQsDHxIvSqjrd0gBkuA9xavp7FkEiX19yTnorFdKYud\n\tjtQtquvKPDaleR8eyz3UvLyj5tP8kyzm9lOI78YA="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"m97RPA7u\"; dkim-atps=neutral","Message-ID":"<21627efc-f53a-a3bd-04dc-5046df3cf158@ideasonboard.com>","Date":"Tue, 26 Jul 2022 10:37:36 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.4.1","Content-Language":"en-US","To":"Utkarsh Tiwari <utkarsh02t@gmail.com>","References":"<20220703043704.296872-1-utkarsh02t@gmail.com>\n\t<20220703043704.296872-3-utkarsh02t@gmail.com>\n\t<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>\n\t<CAHbe+E1jkZ5CcWaFBsp2T5cnh3CtZOFEVsOJOT6+TQY3F9Sfmg@mail.gmail.com>","In-Reply-To":"<CAHbe+E1jkZ5CcWaFBsp2T5cnh3CtZOFEVsOJOT6+TQY3F9Sfmg@mail.gmail.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","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":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":24153,"web_url":"https://patchwork.libcamera.org/comment/24153/","msgid":"<20220726173724.GA135666@gmail.com>","date":"2022-07-26T17:37:24","subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","submitter":{"id":114,"url":"https://patchwork.libcamera.org/api/people/114/","name":"Utkarsh Tiwari","email":"utkarsh02t@gmail.com"},"content":"On Tue, Jul 26, 2022 at 10:37:36AM +0530, Umang Jain wrote:\n> Hi Utkarsh,\n> \n> On 7/26/22 07:50, Utkarsh Tiwari wrote:\n> > On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote:\n> > \n> > > Hi Utkarsh,\n> > > \n> > > On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote:\n> > > > Implement an Open Capture Script button which would allow the user\n> > > > to open a Capture Script (*.yaml).\n> > > > This button has two states Open and Stop.\n> > > > \n> > > > Open state allows user to load a capture script.\n> > > > When clicked in open state present them with a QFileDialog\n> > > > to allow user to select a single file.\n> > > > \n> > > > Stop state stops the execution of the current capture script.\n> > > > \n> > > > Introduce a queueCount_ to keep track of the requests queued.\n> > > > \n> > > > When stopping the execution no count is reset and the\n> > > > capture continues as it is.\n> > > \n> > > So there are two states of stop(s) ? One would stop the capture script\n> > > and other one would stop the camera? Is my understanding correct?\n> > > \n> > No, the two states of the button are\n> > - Open Capture Script\n> > - Stop the current capture script\n> > \n> > The  open state allows the user to select a capture script to execute.\n> > \n> > The stop state is visible when the user has loaded a capture script either\n> > through cmdline  or through the button. This state allows to stop the\n> > current script.\n> > \n> > Should reword the commit message ?\n> \n> Yes, it would be helpful.\n> \n> Especially this bit:\n> \n>     When stopping the execution no count is reset and the\n>     capture continues as it is.\n> \n> I also want to ask that we had a recent change where request sequence number\n> are reset to zero on every start()/stop() cycles. So is this a concern this\n> patchset or capture script in general?\n> \n> https://git.libcamera.org/libcamera/libcamera.git/commit/?id=458d917\n  \nI don't think this affects this patchset or the capture script.\nWe need to only the queueCount_ (i.e the frame number) for the capture script.\n\nThe line is meant to say that when the script is stopped we don't restart the\ncapture and nor reset the queueCount_. Qcam resets each counter start() of\nthe capture.\n> \n> > > \n> > > > Requests are queued with any controls the script matching\n> > > > the current queueCount_\n> > > > \n> > > > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com>\n> > > > Reviewed-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(+)\n> > > > \n> > > > diff --git a/src/qcam/assets/feathericons/feathericons.qrc\n> > > b/src/qcam/assets/feathericons/feathericons.qrc\n> > > > index 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> > > >        <file>aperture.svg</file>\n> > > >        <file>camera-off.svg</file>\n> > > > +     <file>file.svg</file>\n> > > >        <file>play-circle.svg</file>\n> > > >        <file>save.svg</file>\n> > > >        <file>stop-circle.svg</file>\n> > > >        <file>x-circle.svg</file>\n> > > > +     <file>x-square.svg</file>\n> > > >    </qresource>\n> > > >    </RCC>\n> > > > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > > > index 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> > > >        saveRaw_ = action;\n> > > >    #endif\n> > > > \n> > > > +     /* Open Script... action. */\n> > > > +     action = toolbar_->addAction(QIcon::fromTheme(\"document-open\",\n> > > > +                                                   QIcon(\":file.svg\")),\n> > > > +                                  \"Open Capture Script\");\n> > > > +     connect(action, &QAction::triggered, this,\n> > > &MainWindow::chooseScript);\n> > > > +     scriptExecAction_ = action;\n> > > > +\n> > > >        return 0;\n> > > >    }\n> > > > \n> > > > @@ -255,6 +263,60 @@ void MainWindow::updateTitle()\n> > > >        setWindowTitle(title_ + \" : \" + QString::number(fps, 'f', 2) + \"\n> > > 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> > > > +     if (script_) {\n> > > > +             /*\n> > > > +              * This is the second valid press of load script button,\n> > > > +              * It indicates stopping, Stop and set button for new\n> > > script.\n> > > > +              */\n> > > > +             script_.reset();\n> > > > +\n> > >   scriptExecAction_->setIcon(QIcon::fromTheme(\"document-open\",\n> > > > +\n> > >   QIcon(\":file.svg\")));\n> > > > +             scriptExecAction_->setText(\"Open Capture Script\");\n> > > > +             return;\n> > > > +     }\n> > > > +\n> > > > +     QString scriptFile = QFileDialog::getOpenFileName(this, \"Open\n> > > Capture Script\", QDir::currentPath(),\n> > > > +                                                       \"Capture Script\n> > > (*.yaml)\");\n> > > > +     if (scriptFile.isEmpty())\n> > > > +             return;\n> > > > +\n> > > > +     /*\n> > > > +      * If we are already capturing,\n> > > > +      * stop so we don't have stuck image in viewfinder.\n> > > > +      */\n> > > > +     bool wasCapturing = isCapturing_;\n> > > > +     if (isCapturing_)\n> > > > +             toggleCapture(false);\n> > > > +\n> > > > +     script_ = std::make_unique<CaptureScript>(camera_,\n> > > scriptFile.toStdString());\n> > > > +     if (!script_->valid()) {\n> > > > +             script_.reset();\n> > > > +             QMessageBox::critical(this, \"Invalid Script\",\n> > > > +                                           \"Couldn't load the capture\n> > > script\");\n> > > > +             if (wasCapturing)\n> > > > +                     toggleCapture(true);\n> > > > +             return;\n> > > > +     }\n> > > > +\n> > > > +     /*\n> > > > +      * Valid script verified\n> > > > +      * Set the button to indicate stopping availibility.\n> > > > +      */\n> > > > +     scriptExecAction_->setIcon(QIcon(\":x-square.svg\"));\n> > > > +     scriptExecAction_->setText(\"Stop Script execution\");\n> > > > +\n> > > > +     /* Start capture again if we were capturing before. */\n> > > > +     if (wasCapturing)\n> > > > +             toggleCapture(true);\n> > > > +}\n> > > > +\n> > > >    /*\n> > > -----------------------------------------------------------------------------\n> > > >     * Camera Selection\n> > > >     */\n> > > > @@ -510,6 +572,7 @@ int MainWindow::startCapture()\n> > > >        previousFrames_ = 0;\n> > > >        framesCaptured_ = 0;\n> > > >        lastBufferTime_ = 0;\n> > > > +     queueCount_ = 0;\n> > > > \n> > > >        ret = camera_->start();\n> > > >        if (ret) {\n> > > > @@ -789,5 +852,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)\n> > > > \n> > > >    int MainWindow::queueRequest(Request *request)\n> > > >    {\n> > > > +     if (script_)\n> > > > +             request->controls() = script_->frameControls(queueCount_);\n> > > > +\n> > > > +     queueCount_++;\n> > > > +\n> > > >        return camera_->queueRequest(request);\n> > > >    }\n> > > > diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> > > > index 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> > > >        void processHotplug(HotplugEvent *e);\n> > > >        void processViewfinder(libcamera::FrameBuffer *buffer);\n> > > > \n> > > > +     void chooseScript();\n> > > > +\n> > > >        /* UI elements */\n> > > >        QToolBar *toolbar_;\n> > > >        QAction *startStopAction_;\n> > > >        QComboBox *cameraCombo_;\n> > > >        QAction *saveRaw_;\n> > > > +     QAction *scriptExecAction_;\n> > > >        ViewFinder *viewfinder_;\n> > > > \n> > > >        QIcon iconPlay_;\n> > > > @@ -124,6 +128,8 @@ private:\n> > > >        QElapsedTimer frameRateInterval_;\n> > > >        uint32_t previousFrames_;\n> > > >        uint32_t framesCaptured_;\n> > > > +     uint32_t queueCount_;\n> > > > \n> > > >        std::vector<std::unique_ptr<libcamera::Request>> requests_;\n> > > > +     std::unique_ptr<CaptureScript> script_;\n> > > >    };\n> > > > diff --git a/src/qcam/meson.build b/src/qcam/meson.build\n> > > > index 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> > > >","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 23D34C3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Jul 2022 17:37:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D644763312;\n\tTue, 26 Jul 2022 19:37:32 +0200 (CEST)","from mail-pl1-x636.google.com (mail-pl1-x636.google.com\n\t[IPv6:2607:f8b0:4864:20::636])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A34E460487\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Jul 2022 19:37:31 +0200 (CEST)","by mail-pl1-x636.google.com with SMTP id d7so13960605plr.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Jul 2022 10:37:31 -0700 (PDT)","from gmail.com ([2404:bd00:3:db95:24ba:12c1:c8f1:3cb1])\n\tby smtp.gmail.com with ESMTPSA id\n\ts18-20020a170902ea1200b0016bf9437766sm11915717plg.261.2022.07.26.10.37.28\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 26 Jul 2022 10:37:29 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658857052;\n\tbh=eT2YfOx9C2NKUHZ2SnNSvvS45m/j5/tabBHJPy0xG8c=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=k9lHKOlX0Y4bfV3Q/SK4cKw76WEwMhArkrr82tvFKKh7Eb3LIN6fStXxMZ1Z0DqFY\n\tHpOc43o4DSdceRfLnpiHjzMCUIKy5xOMzJbZ1pl+1fSW2IUk9X+H5at782mKf53I9j\n\t8Ps56a/isr6bg0LC5xO8+KBAWZoph9YxMA+C7YFC5rC50Mc5g5/9/8ywCB9VVjgskW\n\tTFnXjAB1ZnwVgjzHTTcG7fDxdBpthYAI9/nYivlTUl6qXXRdOZXu/Lj2nG4edErSz5\n\tDXTZnig3uTgZxk4/7STozW/DTrjJnoD/7g2kelmg4RjJx+Ju81Oxs7HGmBIwbTJAMZ\n\tuHG1m97m9eVxg==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=date:from:to:cc:subject:message-id:mail-followup-to:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to; bh=itWLdBfhy4cYSPXYSmxBwFtiApujTV9kklW9kVJByc4=;\n\tb=dAIIKvShMNYA3d46FbhRei/jqdHcgZG+zpVe6HngPwFOOedtJjoZi/AFTjXENLTNst\n\td/z7cPjmhwo1vN4TGDaYQrDFD6bVQwEQWqHPHPMdmEyMWodDFToUtt+trCpodc+a8ZSJ\n\tf59MBzWU72F0Yy2hRnx55Kg0n2RUHlgI3K5CDTehwsWCD1gKW9vAsZJ6OUX5LqUAIFgb\n\tURpQV4zQOM0GFxrwjD/DgOMEfVh0O3Sfgk3yalsmZN3ZjDnrcgzivabJUOYKFOqMF1vn\n\tgVEAxfRZqROIxfT32gJMM5V29fPzQxjOkQ/goObJM0T0mirS8FyOV8ZZk5p+nBx2WsMr\n\tn7SA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"dAIIKvSh\"; 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:date:from:to:cc:subject:message-id\n\t:mail-followup-to:references:mime-version:content-disposition\n\t:content-transfer-encoding:in-reply-to;\n\tbh=itWLdBfhy4cYSPXYSmxBwFtiApujTV9kklW9kVJByc4=;\n\tb=gvygThPjEDW+D/I1FmkrrXAzlyzscALqNEbF5pxGz7KYD+dP+56ewm+nF+3Ygfsri6\n\tw7hvXngXyLPp3521q76LR/ZkGiG/f+Sd0JVrOAqxUokIPORZjh72WRrh65exV+a0py9P\n\tHADQAM+anAkZHgVMIW4jkiYTAXQl7n+fJW39Hc9zCCsDZoG9fXeFcNMm922nxww/DPD+\n\tuGsRFb80nbktYF1ZjsybI4SbBwBl+PtOWZdDJazDnGY6l9b1KozH3HNDg1MSojSO/Djk\n\tX/1WmvaUAN1RpjbiprrLvKKiGb7VfN0q2IxP5FNYo7B2FVhd3rwaWge4jWHjkHM8WPDl\n\thiwA==","X-Gm-Message-State":"AJIora8GjZgcrhOdgBHSpYFkm9uy7i/pSOhXmxdJ/tN/DF+6d4kP3ID+\n\tivn9O9Vk/bc7JzLotGvLGO0=","X-Google-Smtp-Source":"AGRyM1sLXHjuZNfortrr4gU1z1DWwhN93GJ/eV+al16qgKAuWaL/J9gmYHvEq+Q0u+GFNb9sRCK1cg==","X-Received":"by 2002:a17:903:32c6:b0:16d:328f:898d with SMTP id\n\ti6-20020a17090332c600b0016d328f898dmr17443661plr.143.1658857049621; \n\tTue, 26 Jul 2022 10:37:29 -0700 (PDT)","Date":"Tue, 26 Jul 2022 23:07:24 +0530","To":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<20220726173724.GA135666@gmail.com>","Mail-Followup-To":"Umang Jain <umang.jain@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20220703043704.296872-1-utkarsh02t@gmail.com>\n\t<20220703043704.296872-3-utkarsh02t@gmail.com>\n\t<044ff178-949c-e6b8-a8ed-eda845e4ff46@ideasonboard.com>\n\t<CAHbe+E1jkZ5CcWaFBsp2T5cnh3CtZOFEVsOJOT6+TQY3F9Sfmg@mail.gmail.com>\n\t<21627efc-f53a-a3bd-04dc-5046df3cf158@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<21627efc-f53a-a3bd-04dc-5046df3cf158@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 2/3] qcam: Add a GUI way to use\n\tcapture script","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]