[libcamera-devel] [PATCH v2 2/3] qcam: Add a GUI way to use capture script
Kieran Bingham
kieran.bingham at ideasonboard.com
Wed Jun 22 17:51:03 CEST 2022
Hi Utkarsh,
Quoting Utkarsh Tiwari via libcamera-devel (2022-06-22 14:16:37)
> Implement an Open Capture Script button which would allow the user
> to open a Capture Script (*.yaml).
> This button has two states Open and Stop.
>
> Open state allows user to load a capture script.
> When clicked in open state present them with a QFileDialog
> to allow user to select a single file.
>
> Stop state stops the execution of the current capture script.
>
> Introduce a queueCount_ to keep track of the requests queued.
>
> When stopping the execution no count is reset and the
> capture continues as it is, this would allow better testing
> as we can stop in between script and observe.
I think it sounds like the right thing to do, but I'm not sure it makes
a difference to testing.
>
> Initialize a Script Parser instance when the user selects
> a valid capture script.
>
> At queueRequest() time if script parser has been initialized,
> then populate the Request::controls() with it at
> queueRequest time providing the queueCount_.
>
> The queueCount_ is incremented after the getting controls from
> the parser, so the first request is for frame 0.
I think the 'useful' information here is that the request is queued with
any controls that are defined in the script matching the current
queueCount_.
>
> Signed-off-by: Utkarsh Tiwari <utkarsh02t at gmail.com>
> ---
> src/qcam/assets/feathericons/feathericons.qrc | 2 +
> src/qcam/main_window.cpp | 61 +++++++++++++++++++
> src/qcam/main_window.h | 7 +++
> src/qcam/meson.build | 2 +
> 4 files changed, 72 insertions(+)
>
> diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc
> index c5302040..6b08395a 100644
> --- a/src/qcam/assets/feathericons/feathericons.qrc
> +++ b/src/qcam/assets/feathericons/feathericons.qrc
> @@ -3,9 +3,11 @@
> <qresource>
> <file>aperture.svg</file>
> <file>camera-off.svg</file>
> + <file>file.svg</file>
> <file>play-circle.svg</file>
> <file>save.svg</file>
> <file>stop-circle.svg</file>
> <file>x-circle.svg</file>
> + <file>x-square.svg</file>
> </qresource>
> </RCC>
> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
> index adeb3181..29da3947 100644
> --- a/src/qcam/main_window.cpp
> +++ b/src/qcam/main_window.cpp
> @@ -20,6 +20,7 @@
> #include <QImage>
> #include <QImageWriter>
> #include <QInputDialog>
> +#include <QMessageBox>
> #include <QMutexLocker>
> #include <QStandardPaths>
> #include <QStringList>
> @@ -232,6 +233,13 @@ int MainWindow::createToolbars()
> saveRaw_ = action;
> #endif
>
> + /* Open Script... action. */
> + action = toolbar_->addAction(QIcon::fromTheme("document-open",
> + QIcon(":file.svg")),
> + "Open Capture Script");
> + connect(action, &QAction::triggered, this, &MainWindow::chooseScript);
> + scriptExecAction_ = action;
> +
> return 0;
> }
>
> @@ -255,6 +263,53 @@ void MainWindow::updateTitle()
> setWindowTitle(title_ + " : " + QString::number(fps, 'f', 2) + " fps");
> }
>
> +/**
> + * \brief Load a capture script for handling the capture session.
> + *
> + * If already capturing, it would restart the capture.
> + */
> +void MainWindow::chooseScript()
> +{
> + if (isScriptExecuting_) {
How about just checking if (script_) rather than adding a new
isScriptExecuting flag?
I think it conveys the same state?
> + /*
> + * This is the second valid press of load script button,
> + * It indicates stopping, Stop and set button for new script
> + */
> + script_.reset();
> + scriptExecAction_->setIcon(QIcon::fromTheme("document-open",
> + QIcon(":file.svg")));
> + scriptExecAction_->setText("Open Capture Script");
> + isScriptExecuting_ = false;
> + return;
> + }
> +
> + QString scriptFile = QFileDialog::getOpenFileName(this, "Open Capture Script", QDir::currentPath(),
> + "Capture Script (*.yaml)");
> + if (scriptFile.isEmpty())
> + return;
New line here I think. It hides the 'return' otherwise.
> + script_ = std::make_unique<CaptureScript>(camera_, scriptFile.toStdString());
> + if (!script_->valid()) {
> + script_.reset();
> + QMessageBox::critical(this, "Invalid Script",
> + "Couldn't load the capture script");
> + return;
> + }
> +
> + /*
> + * Valid script verified
> + * Set the button to indicate stopping availibility
> + */
> + scriptExecAction_->setIcon(QIcon(":x-square.svg"));
> + scriptExecAction_->setText("Stop Script execution");
> + isScriptExecuting_ = true;
> +
> + /* Restart the capture so we can reset every counter */
> + if (isCapturing_) {
> + toggleCapture(false);
> + toggleCapture(true);
> + }
> +}
> +
> /* -----------------------------------------------------------------------------
> * Camera Selection
> */
> @@ -510,6 +565,7 @@ int MainWindow::startCapture()
> previousFrames_ = 0;
> framesCaptured_ = 0;
> lastBufferTime_ = 0;
> + queueCount_ = 0;
>
> ret = camera_->start();
> if (ret) {
> @@ -789,5 +845,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer)
>
> int MainWindow::queueRequest(Request *request)
> {
> + if (script_)
> + request->controls() = script_->frameControls(queueCount_);
> +
> + queueCount_++;
> +
> return camera_->queueRequest(request);
> }
> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
> index c3e4b665..58df4e15 100644
> --- a/src/qcam/main_window.h
> +++ b/src/qcam/main_window.h
> @@ -26,6 +26,7 @@
> #include <libcamera/request.h>
> #include <libcamera/stream.h>
>
> +#include "../cam/capture_script.h"
> #include "../cam/stream_options.h"
> #include "viewfinder.h"
>
> @@ -86,11 +87,14 @@ private:
> void processHotplug(HotplugEvent *e);
> void processViewfinder(libcamera::FrameBuffer *buffer);
>
> + void chooseScript();
> +
> /* UI elements */
> QToolBar *toolbar_;
> QAction *startStopAction_;
> QComboBox *cameraCombo_;
> QAction *saveRaw_;
> + QAction *scriptExecAction_;
> ViewFinder *viewfinder_;
>
> QIcon iconPlay_;
> @@ -112,6 +116,7 @@ private:
>
> /* Capture state, buffers queue and statistics */
> bool isCapturing_;
> + bool isScriptExecuting_;
> bool captureRaw_;
> libcamera::Stream *vfStream_;
> libcamera::Stream *rawStream_;
> @@ -124,6 +129,8 @@ private:
> QElapsedTimer frameRateInterval_;
> uint32_t previousFrames_;
> uint32_t framesCaptured_;
> + uint32_t queueCount_;
>
> std::vector<std::unique_ptr<libcamera::Request>> requests_;
> + std::unique_ptr<CaptureScript> script_;
> };
> diff --git a/src/qcam/meson.build b/src/qcam/meson.build
> index c46f4631..67074252 100644
> --- a/src/qcam/meson.build
> +++ b/src/qcam/meson.build
> @@ -15,6 +15,7 @@ endif
> qcam_enabled = true
>
> qcam_sources = files([
> + '../cam/capture_script.cpp',
> '../cam/image.cpp',
> '../cam/options.cpp',
> '../cam/stream_options.cpp',
> @@ -37,6 +38,7 @@ qcam_resources = files([
> qcam_deps = [
> libatomic,
> libcamera_public,
> + libyaml,
> qt5_dep,
> ]
>
> --
> 2.25.1
>
More information about the libcamera-devel
mailing list