[libcamera-devel] [PATCH 20/21] qcam: viewfinder: Display icon when stopping capture
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Mar 23 18:29:35 CET 2020
Hi Kieran,
On Mon, Mar 23, 2020 at 05:28:05PM +0000, Kieran Bingham wrote:
> On 23/03/2020 14:22, Laurent Pinchart wrote:
> > When stopping capture, display an icon instead of the last frame. This
> > is required to be able to release the last buffer when the viewfinder
> > operators in zero-copy mode.
>
> This is actually really nice because it displays an icon when streams
> fail to start (I have a secondary IR camera on my laptop which is not
> supported, and this icon shows up if I try to stream that camera).
>
> However, it does remove a 'feature' that I had before, where we could
> 'pause' a running stream and have the last image still visible which
> could be useful when trying to catch a picture to save perhaps.
>
> But in general, I think this is a really good feature, and displaying an
> icon for a stream which can't run is more valuable than a pause feature
> which could be added later...
I agree with you, let's take a bit of time to design the pause feature
correctly on top of this.
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> > src/qcam/assets/feathericons/feathericons.qrc | 1 +
> > src/qcam/main_window.cpp | 2 +
> > src/qcam/viewfinder.cpp | 44 ++++++++++++++++++-
> > src/qcam/viewfinder.h | 8 ++++
> > 4 files changed, 54 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc
> > index 6ca3a846803c..c4eb7a0be688 100644
> > --- a/src/qcam/assets/feathericons/feathericons.qrc
> > +++ b/src/qcam/assets/feathericons/feathericons.qrc
> > @@ -1,5 +1,6 @@
> > <!DOCTYPE RCC><RCC version="1.0">
> > <qresource>
> > +<file>./camera-off.svg</file>
> > <file>./play-circle.svg</file>
> > <file>./save.svg</file>
> > <file>./stop-circle.svg</file>
> > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
> > index b68e171c5e01..a77d10bb7076 100644
> > --- a/src/qcam/main_window.cpp
> > +++ b/src/qcam/main_window.cpp
> > @@ -412,6 +412,8 @@ void MainWindow::stopCapture()
> > if (!isCapturing_)
> > return;
> >
> > + viewfinder_->stop();
> > +
> > int ret = camera_->stop();
> > if (ret)
> > qInfo() << "Failed to stop capture";
> > diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp
> > index 4c35659e24aa..a40b2b400daa 100644
> > --- a/src/qcam/viewfinder.cpp
> > +++ b/src/qcam/viewfinder.cpp
> > @@ -20,6 +20,7 @@
> > ViewFinder::ViewFinder(QWidget *parent)
> > : QWidget(parent), buffer_(nullptr)
> > {
> > + icon_ = QIcon(":camera-off.svg");
> > }
> >
> > ViewFinder::~ViewFinder()
> > @@ -89,6 +90,18 @@ void ViewFinder::render(libcamera::FrameBuffer *buffer, MappedBuffer *map)
> > renderComplete(buffer);
> > }
> >
> > +void ViewFinder::stop()
> > +{
> > + image_ = QImage();
> > +
> > + if (buffer_) {
> > + renderComplete(buffer_);
> > + buffer_ = nullptr;
> > + }
> > +
> > + update();
> > +}
> > +
> > QImage ViewFinder::getCurrentImage()
> > {
> > QMutexLocker locker(&mutex_);
> > @@ -99,7 +112,36 @@ QImage ViewFinder::getCurrentImage()
> > void ViewFinder::paintEvent(QPaintEvent *)
> > {
> > QPainter painter(this);
> > - painter.drawImage(rect(), image_, image_.rect());
> > +
> > + /* If we have an image, draw it. */
> > + if (!image_.isNull()) {
> > + painter.drawImage(rect(), image_, image_.rect());
> > + return;
> > + }
> > +
> > + /*
> > + * Otherwise, draw the camera stopped icon. Render it to the pixmap if
> > + * the size has changed.
> > + */
> > + constexpr int margin = 20;
> > +
> > + if (vfSize_ != size() || pixmap_.isNull()) {
> > + vfSize_ = size();
> > +
> > + QSize pixmapSize{ 1, 1 };
> > + pixmapSize.scale(vfSize_.shrunkBy({ margin, margin, margin, margin }),
>
> shrunkBy fails to compile on QT 5.12.2 ... but you already know (and
> have fixed) that...
>
> > + Qt::KeepAspectRatio);
> > + pixmap_ = icon_.pixmap(pixmapSize);
> > + }
> > +
> > + QPoint point{ margin, margin };
> > + if (pixmap_.width() < width() - 2 * margin)
> > + point.setX((width() - pixmap_.width()) / 2);
> > + else
> > + point.setY((height() - pixmap_.height()) / 2);
> > +
> > + painter.setBackgroundMode(Qt::OpaqueMode);
> > + painter.drawPixmap(point, pixmap_);
> > }
> >
> > QSize ViewFinder::sizeHint() const
> > diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h
> > index b5153160f70e..1a27f99ea202 100644
> > --- a/src/qcam/viewfinder.h
> > +++ b/src/qcam/viewfinder.h
> > @@ -9,6 +9,7 @@
> >
> > #include <stddef.h>
> >
> > +#include <QIcon>
> > #include <QImage>
> > #include <QMutex>
> > #include <QSize>
> > @@ -36,6 +37,7 @@ public:
> >
> > int setFormat(const libcamera::PixelFormat &format, const QSize &size);
> > void render(libcamera::FrameBuffer *buffer, MappedBuffer *map);
> > + void stop();
> >
> > QImage getCurrentImage();
> >
> > @@ -52,6 +54,12 @@ private:
> > libcamera::PixelFormat format_;
> > QSize size_;
> >
> > + /* Camera stopped icon */
> > + QSize vfSize_;
> > + QIcon icon_;
> > + QPixmap pixmap_;
> > +
> > + /* Buffer and render image */
> > libcamera::FrameBuffer *buffer_;
> > QImage image_;
> > QMutex mutex_; /* Prevent concurrent access to image_ */
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list