6#include <QtMultimedia/private/qplatformcamera_p.h>
7#include <QtMultimedia/private/qplatformimagecapture_p.h>
8#include <QtMultimedia/qvideoframeformat.h>
9#include <QtMultimedia/private/qmediastoragelocation_p.h>
10#include <QtCore/qdebug.h>
11#include <QtCore/qdir.h>
12#include <QtCore/qstandardpaths.h>
13#include <QtCore/qloggingcategory.h>
47 videoConvert(
std::move(videoconvert)),
48 encoder(
std::move(jpegenc)),
49 muxer(
std::move(jifmux))
55 queue.set(
"leaky", 2 );
56 queue.set(
"silent",
true);
65 sink.set(
"async",
false);
71 addProbeToPad(
queue.staticPad(
"src").pad(),
false);
73 sink.set(
"signal-handoffs",
true);
74 m_handoffConnection =
sink.connect(
"handoff", G_CALLBACK(&saveImageFilter),
this);
82 auto pendingFutures = [&] {
84 return std::move(m_pendingFutures);
87 for (QFuture<void> &pendingImage : pendingFutures)
88 pendingImage.waitForFinished();
94 return m_session && !passImage && cameraActive;
102 return doCapture(
path);
112 qCDebug(qLcImageCaptureGst) <<
"do capture";
116 auto invokeDeferred = [&](
auto &&fn) {
122 invokeDeferred([
this] {
127 qCDebug(qLcImageCaptureGst) <<
"error 1";
130 if (!m_session->
camera()) {
131 invokeDeferred([
this] {
135 qCDebug(qLcImageCaptureGst) <<
"error 2";
139 invokeDeferred([
this] {
144 qCDebug(qLcImageCaptureGst) <<
"error 3";
157void QGstreamerImageCapture::setResolution(
const QSize &resolution)
160 if (padCaps.isNull()) {
161 qDebug() <<
"Camera not ready";
168 gst_caps_set_simple(caps.
caps(),
"width", G_TYPE_INT, resolution.
width(),
"height", G_TYPE_INT,
169 resolution.
height(),
nullptr);
179 qCDebug(qLcImageCaptureGst) <<
"probe buffer";
193 GstVideoInfo previewInfo;
196 if (optionalFormatAndVideoInfo)
197 std::tie(
fmt, previewInfo) = std::move(*optionalFormatAndVideoInfo);
201 std::move(bufferHandle), previewInfo,
sink,
fmt, memoryFormat,
206 qDebug() <<
"received a null image";
214 qCDebug(qLcImageCaptureGst) <<
"Image available!";
232 if (m_session == captureSession)
237 disconnect(m_session,
nullptr,
this,
nullptr);
239 pendingImages.
clear();
241 cameraActive =
false;
244 m_session = captureSession;
269 qCDebug(qLcImageCaptureGst) <<
"cameraActiveChanged" << cameraActive << active;
270 if (cameraActive == active)
272 cameraActive = active;
280 if (m_session->
camera()) {
289gboolean QGstreamerImageCapture::saveImageFilter(GstElement *, GstBuffer *
buffer, GstPad *,
296void QGstreamerImageCapture::saveBufferToImage(GstBuffer *
buffer)
308 int id = futureIDAllocator++;
318 m_pendingFutures.
remove(
id);
325 qCDebug(qLcImageCaptureGst) <<
" could not open image file for writing";
330 GstBuffer *
buffer = bufferHandle.get();
331 if (gst_buffer_map(
buffer, &
info, GST_MAP_READ)) {
332 f.write(
reinterpret_cast<const char *
>(
info.data),
info.size);
342 m_pendingFutures.
insert(
id, saveImageFuture);
355 setResolution(resolution);
363#include "moc_qgstreamerimagecapture_p.cpp"
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QGstBin create(const char *name)
MemoryFormat memoryFormat() const
std::optional< std::pair< QVideoFrameFormat, GstVideoInfo > > formatAndVideoInfo() const
bool setStateSync(GstState state, std::chrono::nanoseconds timeout=std::chrono::seconds(1))
QGstPad staticPad(const char *name) const
static QGstElement createFromFactory(const char *factory, const char *name=nullptr)
QGstCaps currentCaps() const
int capture(const QString &fileName) override
bool isReadyForCapture() const override
virtual ~QGstreamerImageCapture()
bool probeBuffer(GstBuffer *buffer) override
QImageEncoderSettings imageSettings() const override
int captureToBuffer() override
void setImageSettings(const QImageEncoderSettings &settings) override
void cameraActiveChanged(bool active)
void setMetaData(const QMediaMetaData &m) override
void setCaptureSession(QPlatformMediaCaptureSession *session)
bool isEmpty() const noexcept
iterator insert(const Key &key, const T &value)
size_type remove(const Key &key)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void enqueue(const T &t)
Adds value t to the tail of the queue.
T & head()
Returns a reference to the queue's head item.
T dequeue()
Removes the head item in the queue and returns it.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
The QVideoFrame class represents a frame of video data.
Combined button and popup list for selecting options.
QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args)
QTextStream & bin(QTextStream &stream)
Calls QTextStream::setIntegerBase(2) on stream and returns stream.
DBusConnection const char DBusError * error
std::enable_if_t<(std::is_base_of_v< QGstElement, Ts > &&...), void qLinkGstElements)(const Ts &...ts)
QString errorMessageCannotFindElement(std::string_view element)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
GLsizei GLenum GLboolean sink
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
unsigned long long quint64
QVideoFrameFormat::PixelFormat fmt
QSettings settings("MySoft", "Star Runner")
[0]
myObject disconnect()
[26]