10#include <private/qmediastoragelocation_p.h>
12#include <QtCore/qfileinfo.h>
13#include <QtCore/qfuture.h>
14#include <QtCore/qpromise.h>
15#include <QtCore/qthread.h>
17#include <camera/camera_api.h>
19using namespace Qt::Literals::StringLiterals;
24 case QImageCapture::JPEG:
26 case QImageCapture::PNG:
28 case QImageCapture::WebP:
29 case QImageCapture::Tiff:
30 case QImageCapture::UnspecifiedFormat:
39 const QString extension = formatExtension(format);
41 if (extension.isEmpty())
44 if (fileName.isEmpty()) {
45 return QMediaStorageLocation::generateFileName(QString(),
46 QStandardPaths::PicturesLocation, extension);
49 if (fileName.endsWith(extension))
50 return QFileInfo(fileName).canonicalFilePath();
52 QString path = fileName;
53 path.append(u".%1"_s.arg(extension));
55 return QFileInfo(path).canonicalFilePath();
60QQnxImageCapture::QQnxImageCapture(QImageCapture *parent)
61 : QPlatformImageCapture(parent)
73 Q_EMIT error(-1, QImageCapture::NotReadyError, QPlatformImageCapture::msgCameraNotReady());
78 const QImageCapture::FileFormat format =
79 m_settings.format() == QImageCapture::UnspecifiedFormat
80 ? QImageCapture::PNG : m_settings.format();
82 const QString resolvedFileName = resolveFileName(fileName, format);
84 if (resolvedFileName.isEmpty()) {
85 const QString errorMessage = (u"Invalid file format: %1"_s).arg(
86 QImageCapture::fileFormatName(format));
88 Q_EMIT error(-1, QImageCapture::NotSupportedFeatureError, errorMessage);
92 const int id = m_lastId++;
94 auto callback = [
this, id, fn=std::move(resolvedFileName)](
const QVideoFrame &frame) {
95 saveFrame(id, frame, fn);
98 m_camera->requestVideoFrame(
std::move(callback));
106 Q_EMIT error(-1, QImageCapture::NotReadyError, QPlatformImageCapture::msgCameraNotReady());
110 const int id = m_lastId++;
112 auto callback = [
this, id](
const QVideoFrame &frame) { decodeFrame(id, frame); };
114 m_camera->requestVideoFrame(
std::move(callback));
119QFuture<QImage>
QQnxImageCapture::decodeFrame(
int id,
const QVideoFrame &frame)
121 if (!frame.isValid()) {
122 Q_EMIT error(id, QImageCapture::NotReadyError, u"Invalid frame"_s);
126 QPromise<QImage> promise;
127 QFuture<QImage> future = promise.future();
131 auto runner = [frame, promise=std::move(promise)]()
mutable {
133 promise.addResult(frame.toImage());
137 auto *worker = QThread::create(std::move(runner));
139 auto onFinished = [
this, worker, id, future]()
mutable {
140 worker->deleteLater();
142 if (future.isValid()) {
143 Q_EMIT imageCaptured(id, future.result());
145 qWarning(
"QQnxImageCapture: failed to capture image to buffer");
149 connect(worker, &QThread::finished,
this, std::move(onFinished));
151 Q_EMIT imageExposed(id);
158void QQnxImageCapture::saveFrame(
int id,
const QVideoFrame &frame,
const QString &fileName)
160 QFuture<QImage> decodeFuture = decodeFrame(id, frame);
162 if (decodeFuture.isCanceled())
165 QPromise<
bool> promise;
166 QFuture<
bool> saveFuture = promise.future();
170 auto runner = [future=std::move(decodeFuture),
171 promise=std::move(promise), fileName]()
mutable {
173 promise.addResult(future.result().save(fileName));
177 auto *worker = QThread::create(std::move(runner));
179 auto onFinished = [
this, worker, id, future=std::move(saveFuture), fn=std::move(fileName)]() {
180 worker->deleteLater();
182 if (future.isValid() && future.result())
183 Q_EMIT imageSaved(id, fn);
185 Q_EMIT error(id, QImageCapture::NotSupportedFeatureError, u"Failed to save image"_s);
188 connect(worker, &QThread::finished,
this, std::move(onFinished));
200 m_settings = settings;
205 if (m_session == captureSession)
209 m_session->disconnect(
this);
211 m_session = captureSession;
214 connect(m_session, &QQnxMediaCaptureSession::cameraChanged,
215 this, &QQnxImageCapture::onCameraChanged);
224 m_camera->disconnect(
this);
226 m_camera = m_session ?
static_cast<
QQnxPlatformCamera*>(m_session->camera()) :
nullptr;
229 connect(m_camera, &QQnxPlatformCamera::activeChanged,
230 this, &QQnxImageCapture::onCameraChanged);
233 updateReadyForCapture();
240 updateReadyForCapture();
247 if (m_lastReadyForCapture == readyForCapture)
250 m_lastReadyForCapture = readyForCapture;
252 Q_EMIT readyForCaptureChanged(m_lastReadyForCapture);
257#include "moc_qqnximagecapture_p.cpp"
void setImageSettings(const QImageEncoderSettings &settings) override
QImageEncoderSettings imageSettings() const override
void setCaptureSession(QQnxMediaCaptureSession *session)
int captureToBuffer() override
int capture(const QString &fileName) override
bool isReadyForCapture() const override
static QString resolveFileName(const QString &fileName, QImageCapture::FileFormat format)
static QString formatExtension(QImageCapture::FileFormat format)