Message ID | 20220703043704.296872-3-utkarsh02t@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
On Sun, Jul 3, 2022 at 12:37 PM Utkarsh Tiwari <utkarsh02t@gmail.com> wrote: > 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> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > src/qcam/assets/feathericons/feathericons.qrc | 2 + > src/qcam/main_window.cpp | 68 +++++++++++++++++++ > src/qcam/main_window.h | 6 ++ > src/qcam/meson.build | 2 + > 4 files changed, 78 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..4fbaeccc 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,60 @@ 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"); > This is wrongly indented and should be 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 +572,7 @@ int MainWindow::startCapture() > previousFrames_ = 0; > framesCaptured_ = 0; > lastBufferTime_ = 0; > + queueCount_ = 0; > > ret = camera_->start(); > if (ret) { > @@ -789,5 +852,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 > >
Hi Utkarsh, On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote: > 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. So there are two states of stop(s) ? One would stop the capture script and other one would stop the camera? Is my understanding correct? > > Requests are queued with any controls the script matching > the current queueCount_ > > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > src/qcam/assets/feathericons/feathericons.qrc | 2 + > src/qcam/main_window.cpp | 68 +++++++++++++++++++ > src/qcam/main_window.h | 6 ++ > src/qcam/meson.build | 2 + > 4 files changed, 78 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..4fbaeccc 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,60 @@ 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 +572,7 @@ int MainWindow::startCapture() > previousFrames_ = 0; > framesCaptured_ = 0; > lastBufferTime_ = 0; > + queueCount_ = 0; > > ret = camera_->start(); > if (ret) { > @@ -789,5 +852,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, > ] >
On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote: > Hi Utkarsh, > > On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote: > > 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. > > > So there are two states of stop(s) ? One would stop the capture script > and other one would stop the camera? Is my understanding correct? > No, the two states of the button are - Open Capture Script - Stop the current capture script The open state allows the user to select a capture script to execute. The stop state is visible when the user has loaded a capture script either through cmdline or through the button. This state allows to stop the current script. Should reword the commit message ? > > > > > > Requests are queued with any controls the script matching > > the current queueCount_ > > > > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > --- > > src/qcam/assets/feathericons/feathericons.qrc | 2 + > > src/qcam/main_window.cpp | 68 +++++++++++++++++++ > > src/qcam/main_window.h | 6 ++ > > src/qcam/meson.build | 2 + > > 4 files changed, 78 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..4fbaeccc 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,60 @@ 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 +572,7 @@ int MainWindow::startCapture() > > previousFrames_ = 0; > > framesCaptured_ = 0; > > lastBufferTime_ = 0; > > + queueCount_ = 0; > > > > ret = camera_->start(); > > if (ret) { > > @@ -789,5 +852,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, > > ] > > >
Hi Utkarsh, On 7/26/22 07:50, Utkarsh Tiwari wrote: > On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote: > >> Hi Utkarsh, >> >> On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote: >>> 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. >> >> So there are two states of stop(s) ? One would stop the capture script >> and other one would stop the camera? Is my understanding correct? >> > No, the two states of the button are > - Open Capture Script > - Stop the current capture script > > The open state allows the user to select a capture script to execute. > > The stop state is visible when the user has loaded a capture script either > through cmdline or through the button. This state allows to stop the > current script. > > Should reword the commit message ? Yes, it would be helpful. Especially this bit: When stopping the execution no count is reset and the capture continues as it is. I also want to ask that we had a recent change where request sequence number are reset to zero on every start()/stop() cycles. So is this a concern this patchset or capture script in general? https://git.libcamera.org/libcamera/libcamera.git/commit/?id=458d917 >> >>> Requests are queued with any controls the script matching >>> the current queueCount_ >>> >>> Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> >>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> >>> --- >>> src/qcam/assets/feathericons/feathericons.qrc | 2 + >>> src/qcam/main_window.cpp | 68 +++++++++++++++++++ >>> src/qcam/main_window.h | 6 ++ >>> src/qcam/meson.build | 2 + >>> 4 files changed, 78 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..4fbaeccc 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,60 @@ 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 +572,7 @@ int MainWindow::startCapture() >>> previousFrames_ = 0; >>> framesCaptured_ = 0; >>> lastBufferTime_ = 0; >>> + queueCount_ = 0; >>> >>> ret = camera_->start(); >>> if (ret) { >>> @@ -789,5 +852,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, >>> ] >>>
On Tue, Jul 26, 2022 at 10:37:36AM +0530, Umang Jain wrote: > Hi Utkarsh, > > On 7/26/22 07:50, Utkarsh Tiwari wrote: > > On Tue, 26 Jul, 2022, 00:14 Umang Jain, <umang.jain@ideasonboard.com> wrote: > > > > > Hi Utkarsh, > > > > > > On 7/3/22 10:07, Utkarsh Tiwari via libcamera-devel wrote: > > > > 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. > > > > > > So there are two states of stop(s) ? One would stop the capture script > > > and other one would stop the camera? Is my understanding correct? > > > > > No, the two states of the button are > > - Open Capture Script > > - Stop the current capture script > > > > The open state allows the user to select a capture script to execute. > > > > The stop state is visible when the user has loaded a capture script either > > through cmdline or through the button. This state allows to stop the > > current script. > > > > Should reword the commit message ? > > Yes, it would be helpful. > > Especially this bit: > > When stopping the execution no count is reset and the > capture continues as it is. > > I also want to ask that we had a recent change where request sequence number > are reset to zero on every start()/stop() cycles. So is this a concern this > patchset or capture script in general? > > https://git.libcamera.org/libcamera/libcamera.git/commit/?id=458d917 I don't think this affects this patchset or the capture script. We need to only the queueCount_ (i.e the frame number) for the capture script. The line is meant to say that when the script is stopped we don't restart the capture and nor reset the queueCount_. Qcam resets each counter start() of the capture. > > > > > > > > Requests are queued with any controls the script matching > > > > the current queueCount_ > > > > > > > > Signed-off-by: Utkarsh Tiwari <utkarsh02t@gmail.com> > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > > > --- > > > > src/qcam/assets/feathericons/feathericons.qrc | 2 + > > > > src/qcam/main_window.cpp | 68 +++++++++++++++++++ > > > > src/qcam/main_window.h | 6 ++ > > > > src/qcam/meson.build | 2 + > > > > 4 files changed, 78 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..4fbaeccc 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,60 @@ 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 +572,7 @@ int MainWindow::startCapture() > > > > previousFrames_ = 0; > > > > framesCaptured_ = 0; > > > > lastBufferTime_ = 0; > > > > + queueCount_ = 0; > > > > > > > > ret = camera_->start(); > > > > if (ret) { > > > > @@ -789,5 +852,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, > > > > ] > > > >
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..4fbaeccc 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,60 @@ 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 +572,7 @@ int MainWindow::startCapture() previousFrames_ = 0; framesCaptured_ = 0; lastBufferTime_ = 0; + queueCount_ = 0; ret = camera_->start(); if (ret) { @@ -789,5 +852,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, ]