Message ID | 20220627030159.30730-3-utkarsh02t@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Quoting Utkarsh Tiwari via libcamera-devel (2022-06-27 04:01:58) > 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. > > Requests are queued with any controls the script matching > the current queueCount_ > > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> > --- > src/qcam/assets/feathericons/feathericons.qrc | 2 + > src/qcam/main_window.cpp | 66 +++++++++++++++++++ > src/qcam/main_window.h | 6 ++ > src/qcam/meson.build | 2 + > 4 files changed, 76 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..e133b618 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,58 @@ 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 (script_) { > + /* > + * 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"); > + return; > + } > + > + QString scriptFile = QFileDialog::getOpenFileName(this, "Open Capture Script", QDir::currentPath(), > + "Capture Script (*.yaml)"); > + if (scriptFile.isEmpty()) > + return; > + > + /* If we are already capturing, > + * stop so we don't have stuck image in viewfinder. */ Our coding style uses block quotes with /* and */ on their own lines. /* * If we are already capturing, stop so we don't have a stuck * image in the viewfinder. */ What causes a stuck image? Is it while the script is being loaded and parsed? It seems reasonable to stop as we're going to have to do a restart anyway. > + bool wasCapturing_ = isCapturing_; Local variables don't use the _ at the end. That signifies that the variable is a class variable. With those fixed, you can add: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > + if(isCapturing_) > + toggleCapture(false); > + > + script_ = std::make_unique<CaptureScript>(camera_, scriptFile.toStdString()); > + if (!script_->valid()) { > + script_.reset(); > + QMessageBox::critical(this, "Invalid Script", > + "Couldn't load the capture script"); > + if(wasCapturing_) > + toggleCapture(true); > + return; > + } > + > + /* > + * Valid script verified > + * Set the button to indicate stopping availibility. > + */ > + scriptExecAction_->setIcon(QIcon(":x-square.svg")); > + scriptExecAction_->setText("Stop Script execution"); > + > + /* Start capture again if we were capturing before. */ > + if(wasCapturing_) > + toggleCapture(true); > +} > + > /* ----------------------------------------------------------------------------- > * Camera Selection > */ > @@ -510,6 +570,7 @@ int MainWindow::startCapture() > previousFrames_ = 0; > framesCaptured_ = 0; > lastBufferTime_ = 0; > + queueCount_ = 0; > > ret = camera_->start(); > if (ret) { > @@ -789,5 +850,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..2cdf7169 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_; > @@ -124,6 +128,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 >
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..e133b618 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,58 @@ 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 (script_) { + /* + * 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"); + return; + } + + QString scriptFile = QFileDialog::getOpenFileName(this, "Open Capture Script", QDir::currentPath(), + "Capture Script (*.yaml)"); + if (scriptFile.isEmpty()) + return; + + /* If we are already capturing, + * stop so we don't have stuck image in viewfinder. */ + bool wasCapturing_ = isCapturing_; + if(isCapturing_) + toggleCapture(false); + + script_ = std::make_unique<CaptureScript>(camera_, scriptFile.toStdString()); + if (!script_->valid()) { + script_.reset(); + QMessageBox::critical(this, "Invalid Script", + "Couldn't load the capture script"); + if(wasCapturing_) + toggleCapture(true); + return; + } + + /* + * Valid script verified + * Set the button to indicate stopping availibility. + */ + scriptExecAction_->setIcon(QIcon(":x-square.svg")); + scriptExecAction_->setText("Stop Script execution"); + + /* Start capture again if we were capturing before. */ + if(wasCapturing_) + toggleCapture(true); +} + /* ----------------------------------------------------------------------------- * Camera Selection */ @@ -510,6 +570,7 @@ int MainWindow::startCapture() previousFrames_ = 0; framesCaptured_ = 0; lastBufferTime_ = 0; + queueCount_ = 0; ret = camera_->start(); if (ret) { @@ -789,5 +850,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..2cdf7169 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_; @@ -124,6 +128,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, ]
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. Requests are queued with any controls the script matching the current queueCount_ Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> --- src/qcam/assets/feathericons/feathericons.qrc | 2 + src/qcam/main_window.cpp | 66 +++++++++++++++++++ src/qcam/main_window.h | 6 ++ src/qcam/meson.build | 2 + 4 files changed, 76 insertions(+)