summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp')
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp134
1 files changed, 50 insertions, 84 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp b/src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp
index fe8df22b7..2fb878784 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp
+++ b/src/plugins/multimedia/ffmpeg/qffmpegimagecapture.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qffmpegimagecapture_p.h"
#include <private/qplatformmediaformatinfo_p.h>
@@ -53,11 +17,15 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qLcImageCapture, "qt.multimedia.imageCapture")
+// Probably, might be increased. To be investigated and tested on Android implementation
+static constexpr int MaxPendingImagesCount = 1;
+
+static Q_LOGGING_CATEGORY(qLcImageCapture, "qt.multimedia.imageCapture")
QFFmpegImageCapture::QFFmpegImageCapture(QImageCapture *parent)
: QPlatformImageCapture(parent)
{
+ qRegisterMetaType<QVideoFrame>();
}
QFFmpegImageCapture::~QFFmpegImageCapture()
@@ -115,7 +83,7 @@ int QFFmpegImageCapture::doCapture(const QString &fileName)
qCDebug(qLcImageCapture) << "error 1";
return -1;
}
- if (!m_camera) {
+ if (!m_videoSource) {
//emit error in the next event loop,
//so application can associate it with returned request id.
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
@@ -126,7 +94,7 @@ int QFFmpegImageCapture::doCapture(const QString &fileName)
qCDebug(qLcImageCapture) << "error 2";
return -1;
}
- if (passImage) {
+ if (m_pendingImages.size() >= MaxPendingImagesCount) {
//emit error in the next event loop,
//so application can associate it with returned request id.
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
@@ -137,13 +105,12 @@ int QFFmpegImageCapture::doCapture(const QString &fileName)
qCDebug(qLcImageCapture) << "error 3";
return -1;
}
- m_lastId++;
- pendingImages.enqueue({m_lastId, fileName, QMediaMetaData{}});
- // let one image pass the pipeline
- passImage = true;
+ m_lastId++;
+ m_pendingImages.enqueue({ m_lastId, fileName, QMediaMetaData{} });
updateReadyForCapture();
+
return m_lastId;
}
@@ -154,48 +121,39 @@ void QFFmpegImageCapture::setCaptureSession(QPlatformMediaCaptureSession *sessio
return;
if (m_session) {
- disconnect(m_session, nullptr, this, nullptr);
+ m_session->disconnect(this);
m_lastId = 0;
- pendingImages.clear();
- passImage = false;
- cameraActive = false;
+ m_pendingImages.clear();
}
m_session = captureSession;
+
if (m_session)
- connect(m_session, &QPlatformMediaCaptureSession::cameraChanged, this, &QFFmpegImageCapture::onCameraChanged);
+ connect(m_session, &QFFmpegMediaCaptureSession::primaryActiveVideoSourceChanged, this,
+ &QFFmpegImageCapture::onVideoSourceChanged);
- onCameraChanged();
- updateReadyForCapture();
+ onVideoSourceChanged();
}
void QFFmpegImageCapture::updateReadyForCapture()
{
- bool ready = m_session && !passImage && cameraActive;
- if (ready == m_isReadyForCapture)
- return;
- m_isReadyForCapture = ready;
- emit readyForCaptureChanged(m_isReadyForCapture);
-}
+ const bool ready = m_session && m_pendingImages.size() < MaxPendingImagesCount && m_videoSource
+ && m_videoSource->isActive();
-void QFFmpegImageCapture::cameraActiveChanged(bool active)
-{
- qCDebug(qLcImageCapture) << "cameraActiveChanged" << cameraActive << active;
- if (cameraActive == active)
- return;
- cameraActive = active;
- qCDebug(qLcImageCapture) << "isReady" << isReadyForCapture();
- updateReadyForCapture();
+ qCDebug(qLcImageCapture) << "updateReadyForCapture" << ready;
+
+ if (std::exchange(m_isReadyForCapture, ready) != ready)
+ emit readyForCaptureChanged(ready);
}
void QFFmpegImageCapture::newVideoFrame(const QVideoFrame &frame)
{
- if (!passImage)
+ if (m_pendingImages.empty())
return;
- passImage = false;
- Q_ASSERT(!pendingImages.isEmpty());
- auto pending = pendingImages.dequeue();
+ auto pending = m_pendingImages.dequeue();
+
+ qCDebug(qLcImageCapture) << "Taking image" << pending.id;
emit imageExposed(pending.id);
// ### Add metadata from the AVFrame
@@ -253,27 +211,33 @@ void QFFmpegImageCapture::newVideoFrame(const QVideoFrame &frame)
emit error(pending.id, err, writer.errorString());
}
}
+
updateReadyForCapture();
}
-void QFFmpegImageCapture::onCameraChanged()
+void QFFmpegImageCapture::setupVideoSourceConnections()
{
- auto *camera = m_session ? m_session->camera() : nullptr;
- if (m_camera == camera)
- return;
+ connect(m_videoSource, &QPlatformCamera::newVideoFrame, this,
+ &QFFmpegImageCapture::newVideoFrame);
+}
+
+QPlatformVideoSource *QFFmpegImageCapture::videoSource() const
+{
+ return m_videoSource;
+}
- if (m_camera)
- disconnect(m_camera);
+void QFFmpegImageCapture::onVideoSourceChanged()
+{
+ if (m_videoSource)
+ m_videoSource->disconnect(this);
- m_camera = camera;
+ m_videoSource = m_session ? m_session->primaryActiveVideoSource() : nullptr;
- if (camera) {
- cameraActiveChanged(camera->isActive());
- connect(camera, &QPlatformCamera::activeChanged, this, &QFFmpegImageCapture::cameraActiveChanged);
- connect(camera, &QPlatformCamera::newVideoFrame, this, &QFFmpegImageCapture::newVideoFrame);
- } else {
- cameraActiveChanged(false);
- }
+ // TODO: optimize, setup the connection only when the capture is ready
+ if (m_videoSource)
+ setupVideoSourceConnections();
+
+ updateReadyForCapture();
}
QImageEncoderSettings QFFmpegImageCapture::imageSettings() const
@@ -303,3 +267,5 @@ void QFFmpegImageCapture::setImageSettings(const QImageEncoderSettings &settings
}
QT_END_NAMESPACE
+
+#include "moc_qffmpegimagecapture_p.cpp"