Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qandroidvideooutput.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <rhi/qrhi.h>
8#include <QtGui/private/qopenglextensions_p.h>
9#include <private/qabstractvideobuffer_p.h>
10#include <private/qvideoframeconverter_p.h>
11#include <private/qplatformvideosink_p.h>
12#include <qvideosink.h>
13#include <qopenglcontext.h>
14#include <qopenglfunctions.h>
15#include <qvideoframeformat.h>
16#include <qthread.h>
17#include <qfile.h>
18
20
22{
23public:
25 {
26 m_tex.reset(rhi->newTexture(QRhiTexture::RGBA8, size, 1));
27 m_tex->createFrom({quint64(handle), 0});
28 }
29
30 QRhiTexture *texture(uint plane) const override
31 {
32 return plane == 0 ? m_tex.get() : nullptr;
33 }
34
35private:
36 std::unique_ptr<QRhiTexture> m_tex;
37};
38
39// QRhiWithThreadGuard keeps QRhi and QThread (that created it) alive to allow proper cleaning
42public:
43 QRhiWithThreadGuard(std::shared_ptr<QRhi> r, std::shared_ptr<AndroidTextureThread> t)
44 : m_guardRhi(std::move(r)), m_thread(std::move(t)) {}
46protected:
47 std::shared_ptr<QRhi> m_guardRhi;
48private:
49 std::shared_ptr<AndroidTextureThread> m_thread;
50};
51
52
54{
55public:
57 std::shared_ptr<QRhi> rhi, std::shared_ptr<AndroidTextureThread> thread,
58 std::unique_ptr<QRhiTexture> tex, const QSize &size)
59 : QRhiWithThreadGuard(std::move(rhi), std::move(thread))
60 , QAbstractVideoBuffer(QVideoFrame::RhiTextureHandle, m_guardRhi.get())
61 , m_size(size)
62 , m_tex(std::move(tex))
63 {}
64
65 QVideoFrame::MapMode mapMode() const override { return m_mapMode; }
66
67 MapData map(QVideoFrame::MapMode mode) override;
68
69 void unmap() override
70 {
71 m_image = {};
72 m_mapMode = QVideoFrame::NotMapped;
73 }
74
75 std::unique_ptr<QVideoFrameTextures> mapTextures(QRhi *rhi) override
76 {
77 return std::make_unique<QAndroidVideoFrameTextures>(rhi, m_size, m_tex->nativeTexture().object);
78 }
79
80private:
81 QSize m_size;
82 std::unique_ptr<QRhiTexture> m_tex;
83 QImage m_image;
85};
86
88{
89public:
91 : QAbstractVideoBuffer(QVideoFrame::RhiTextureHandle, atvb.rhi())
92 , m_atvb(atvb)
93 {}
94 std::unique_ptr<QVideoFrameTextures> mapTextures(QRhi *rhi) override
95 {
96 return m_atvb.mapTextures(rhi);
97 }
99 MapData map(QVideoFrame::MapMode) override { return {}; }
100 void unmap() override {}
101
102private:
104};
105
107{
109
110 if (m_mapMode == QVideoFrame::NotMapped && mode == QVideoFrame::ReadOnly) {
111 m_mapMode = QVideoFrame::ReadOnly;
114 mapData.nPlanes = 1;
115 mapData.bytesPerLine[0] = m_image.bytesPerLine();
116 mapData.size[0] = static_cast<int>(m_image.sizeInBytes());
117 mapData.data[0] = m_image.bits();
118 }
119
120 return mapData;
121}
122
123static const float g_quad[] = {
124 -1.f, -1.f, 0.f, 0.f,
125 -1.f, 1.f, 0.f, 1.f,
126 1.f, 1.f, 1.f, 1.f,
127 1.f, -1.f, 1.f, 0.f
128};
129
131{
132 static QShader getShader(const QString &name)
133 {
134 QFile f(name);
135 if (f.open(QIODevice::ReadOnly))
136 return QShader::fromSerialized(f.readAll());
137 return {};
138 }
139
140public:
141 TextureCopy(QRhi *rhi, QRhiTexture *externalTex)
142 : m_rhi(rhi)
143 {
144 m_vertexBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(g_quad)));
145 m_vertexBuffer->create();
146
147 m_uniformBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 64 + 4 + 4));
148 m_uniformBuffer->create();
149
152 m_sampler->create();
153
154 m_srb.reset(m_rhi->newShaderResourceBindings());
155 m_srb->setBindings({
158 });
159 m_srb->create();
160
161 m_vertexShader = getShader(QStringLiteral(":/qt-project.org/multimedia/shaders/externalsampler.vert.qsb"));
162 Q_ASSERT(m_vertexShader.isValid());
163 m_fragmentShader = getShader(QStringLiteral(":/qt-project.org/multimedia/shaders/externalsampler.frag.qsb"));
164 Q_ASSERT(m_fragmentShader.isValid());
165 }
166
167 std::unique_ptr<QRhiTexture> copyExternalTexture(QSize size, const QMatrix4x4 &externalTexMatrix);
168
169private:
170 QRhi *m_rhi = nullptr;
171 std::unique_ptr<QRhiBuffer> m_vertexBuffer;
172 std::unique_ptr<QRhiBuffer> m_uniformBuffer;
173 std::unique_ptr<QRhiSampler> m_sampler;
174 std::unique_ptr<QRhiShaderResourceBindings> m_srb;
175 QShader m_vertexShader;
176 QShader m_fragmentShader;
177};
178
179static std::unique_ptr<QRhiGraphicsPipeline> newGraphicsPipeline(QRhi *rhi,
180 QRhiShaderResourceBindings *shaderResourceBindings,
181 QRhiRenderPassDescriptor *renderPassDescriptor,
182 QShader vertexShader,
183 QShader fragmentShader)
184{
185 std::unique_ptr<QRhiGraphicsPipeline> gp(rhi->newGraphicsPipeline());
187 gp->setShaderStages({
188 { QRhiShaderStage::Vertex, vertexShader },
189 { QRhiShaderStage::Fragment, fragmentShader }
190 });
191 QRhiVertexInputLayout inputLayout;
192 inputLayout.setBindings({
193 { 4 * sizeof(float) }
194 });
195 inputLayout.setAttributes({
197 { 0, 1, QRhiVertexInputAttribute::Float2, 2 * sizeof(float) }
198 });
199 gp->setVertexInputLayout(inputLayout);
200 gp->setShaderResourceBindings(shaderResourceBindings);
201 gp->setRenderPassDescriptor(renderPassDescriptor);
202 gp->create();
203
204 return gp;
205}
206
207std::unique_ptr<QRhiTexture> TextureCopy::copyExternalTexture(QSize size, const QMatrix4x4 &externalTexMatrix)
208{
209 std::unique_ptr<QRhiTexture> tex(m_rhi->newTexture(QRhiTexture::RGBA8, size, 1, QRhiTexture::RenderTarget));
210 if (!tex->create()) {
211 qWarning("Failed to create frame texture");
212 return {};
213 }
214
215 std::unique_ptr<QRhiTextureRenderTarget> renderTarget(m_rhi->newTextureRenderTarget({ { tex.get() } }));
216 std::unique_ptr<QRhiRenderPassDescriptor> renderPassDescriptor(renderTarget->newCompatibleRenderPassDescriptor());
217 renderTarget->setRenderPassDescriptor(renderPassDescriptor.get());
218 renderTarget->create();
219
220 QRhiResourceUpdateBatch *rub = m_rhi->nextResourceUpdateBatch();
221 rub->uploadStaticBuffer(m_vertexBuffer.get(), g_quad);
222
223 QMatrix4x4 identity;
224 char *p = m_uniformBuffer->beginFullDynamicBufferUpdateForCurrentFrame();
225 memcpy(p, identity.constData(), 64);
226 memcpy(p + 64, externalTexMatrix.constData(), 64);
227 float opacity = 1.0f;
228 memcpy(p + 64 + 64, &opacity, 4);
229 m_uniformBuffer->endFullDynamicBufferUpdateForCurrentFrame();
230
231 auto graphicsPipeline = newGraphicsPipeline(m_rhi, m_srb.get(), renderPassDescriptor.get(),
232 m_vertexShader, m_fragmentShader);
233
234 const QRhiCommandBuffer::VertexInput vbufBinding(m_vertexBuffer.get(), 0);
235
236 QRhiCommandBuffer *cb = nullptr;
237 if (m_rhi->beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess)
238 return {};
239
240 cb->beginPass(renderTarget.get(), Qt::transparent, { 1.0f, 0 }, rub);
241 cb->setGraphicsPipeline(graphicsPipeline.get());
242 cb->setViewport({0, 0, float(size.width()), float(size.height())});
243 cb->setShaderResources(m_srb.get());
244 cb->setVertexInput(0, 1, &vbufBinding);
245 cb->draw(4);
246 cb->endPass();
247 m_rhi->endOffscreenFrame();
248
250 QOpenGLFunctions *f = ctx->functions();
251 static_cast<QOpenGLExtensions *>(f)->flushShared();
252
253 return tex;
254}
255
257{
258 QMatrix4x4 m = surfaceTexture->getTransformMatrix();
259 // flip it back, see
260 // http://androidxref.com/9.0.0_r3/xref/frameworks/native/libs/gui/GLConsumer.cpp#866
261 // (NB our matrix ctor takes row major)
262 static const QMatrix4x4 flipV(1.0f, 0.0f, 0.0f, 0.0f,
263 0.0f, -1.0f, 0.0f, 1.0f,
264 0.0f, 0.0f, 1.0f, 0.0f,
265 0.0f, 0.0f, 0.0f, 1.0f);
266 m *= flipV;
267 return m;
268}
269
271{
273public:
275 : QThread()
276 , m_videoOutput(vo)
277 {
278 }
279
286
287 void start()
288 {
290 moveToThread(this);
291 }
292
294 {
296 params.shareContext = context;
297 params.fallbackSurface = QRhiGles2InitParams::newFallbackSurface();
298 m_rhi.reset(QRhi::create(QRhi::OpenGLES2, &params));
299 }
300
301public slots:
303 {
304 // Check if 'm_surfaceTexture' is not reset and if the current index is the same that
305 // was used for creating connection because there can be pending frames in queue.
306 if (m_surfaceTexture && m_surfaceTexture->index() == index) {
307 m_surfaceTexture->updateTexImage();
308 auto matrix = extTransformMatrix(m_surfaceTexture.get());
309 auto tex = m_textureCopy->copyExternalTexture(m_size, matrix);
310 auto *buffer = new AndroidTextureVideoBuffer(m_rhi, m_videoOutput->getSurfaceThread(), std::move(tex), m_size);
313 }
314 }
315
316 void clearFrame() { emit newFrame({}); }
317
318 void setFrameSize(QSize size) { m_size = size; }
319
321 {
322 m_surfaceTexture.reset();
323 m_texture.reset();
324 m_textureCopy.reset();
325 m_rhi.reset();
326 }
327
329 {
330 if (m_surfaceTexture)
331 return m_surfaceTexture.get();
332
333 QOpenGLContext *ctx = rhi
334 ? static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles())->context
335 : nullptr;
336 initRhi(ctx);
337
338 m_texture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, m_size, 1, QRhiTexture::ExternalOES));
339 m_texture->create();
340 m_surfaceTexture = std::make_unique<AndroidSurfaceTexture>(m_texture->nativeTexture().object);
341 if (m_surfaceTexture->surfaceTexture()) {
342 const quint64 index = m_surfaceTexture->index();
343 connect(m_surfaceTexture.get(), &AndroidSurfaceTexture::frameAvailable, this,
344 [this, index] () { this->onFrameAvailable(index); });
345
346 m_textureCopy = std::make_unique<TextureCopy>(m_rhi.get(), m_texture.get());
347
348 } else {
349 m_texture.reset();
350 m_surfaceTexture.reset();
351 }
352
353 return m_surfaceTexture.get();
354 }
355
356signals:
357 void newFrame(const QVideoFrame &);
358
359private:
360 QAndroidTextureVideoOutput * m_videoOutput;
361 std::shared_ptr<QRhi> m_rhi;
362 std::unique_ptr<AndroidSurfaceTexture> m_surfaceTexture;
363 std::unique_ptr<QRhiTexture> m_texture;
364 std::unique_ptr<TextureCopy> m_textureCopy;
365 QSize m_size;
366};
367
369 // It may happen that reseting m_rhi shared_ptr will delete it (if it is the last reference)
370 // QRHI need to be deleted from the thread that created it.
371 QMetaObject::invokeMethod(m_thread.get(), [&]() {m_guardRhi.reset();}, Qt::BlockingQueuedConnection);
372}
373
375 : QAndroidVideoOutput(parent)
376 , m_sink(sink)
377{
378 if (!m_sink) {
379 qDebug() << "Cannot create QAndroidTextureVideoOutput without a sink.";
380 m_surfaceThread = nullptr;
381 return;
382 }
383
384 startNewSurfaceThread();
385}
386
387void QAndroidTextureVideoOutput::startNewSurfaceThread()
388{
389 m_surfaceThread = std::make_shared<AndroidTextureThread>(this);
390 connect(m_surfaceThread.get(), &AndroidTextureThread::newFrame,
391 this, &QAndroidTextureVideoOutput::newFrame);
392 m_surfaceThread->start();
393}
394
396{
397 // Make sure that no more VideFrames will be created by surfaceThread
398 QMetaObject::invokeMethod(m_surfaceThread.get(),
400}
401
403{
404 if (m_sink) {
405 auto *sink = m_sink->platformVideoSink();
406 if (sink)
407 sink->setSubtitleText(subtitle);
408 }
409}
410
412{
413 return m_sink->rhi() && m_surfaceCreatedWithoutRhi;
414}
415
417{
418 if (!m_sink)
419 return nullptr;
420
422 QMetaObject::invokeMethod(m_surfaceThread.get(), [&]() {
423 auto rhi = m_sink->rhi();
424 if (!rhi) {
425 m_surfaceCreatedWithoutRhi = true;
426 }
427 else if (m_surfaceCreatedWithoutRhi) {
428 m_surfaceThread->clearSurfaceTexture();
429 m_surfaceCreatedWithoutRhi = false;
430 }
431 surface = m_surfaceThread->createSurfaceTexture(rhi);
432 },
434 return surface;
435}
436
438{
439 if (m_nativeSize == size)
440 return;
441
442 m_nativeSize = size;
443 QMetaObject::invokeMethod(m_surfaceThread.get(),
444 [&](){ m_surfaceThread->setFrameSize(size); },
446}
447
449{
450 m_nativeSize = {};
451 QMetaObject::invokeMethod(m_surfaceThread.get(), [&](){ m_surfaceThread->clearFrame(); });
452}
453
460
461void QAndroidTextureVideoOutput::newFrame(const QVideoFrame &frame)
462{
463 if (m_sink)
464 m_sink->setVideoFrame(frame);
465}
466
468
469#include "qandroidvideooutput.moc"
470#include "moc_qandroidvideooutput_p.cpp"
AndroidTextureThread(QAndroidTextureVideoOutput *vo)
void onFrameAvailable(quint64 index)
void newFrame(const QVideoFrame &)
AndroidSurfaceTexture * createSurfaceTexture(QRhi *rhi)
void initRhi(QOpenGLContext *context)
MapData map(QVideoFrame::MapMode mode) override
Independently maps the planes of a video buffer to memory.
QVideoFrame::MapMode mapMode() const override
void unmap() override
Releases the memory mapped by the map() function.
std::unique_ptr< QVideoFrameTextures > mapTextures(QRhi *rhi) override
AndroidTextureVideoBuffer(std::shared_ptr< QRhi > rhi, std::shared_ptr< AndroidTextureThread > thread, std::unique_ptr< QRhiTexture > tex, const QSize &size)
QVideoFrame::MapMode mapMode() const override
void unmap() override
Releases the memory mapped by the map() function.
ImageFromVideoFrameHelper(AndroidTextureVideoBuffer &atvb)
MapData map(QVideoFrame::MapMode) override
Independently maps the planes of a video buffer to memory.
std::unique_ptr< QVideoFrameTextures > mapTextures(QRhi *rhi) override
The QAbstractVideoBuffer class is an abstraction for video data. \inmodule QtMultimedia.
QRhi * rhi() const
Returns the QRhi instance.
void setSubtitle(const QString &subtitle)
QAndroidTextureVideoOutput(QVideoSink *sink, QObject *parent=0)
void setVideoSize(const QSize &) override
std::shared_ptr< AndroidTextureThread > getSurfaceThread()
AndroidSurfaceTexture * surfaceTexture() override
QAndroidVideoFrameTextures(QRhi *rhi, QSize size, quint64 handle)
QRhiTexture * texture(uint plane) const override
\inmodule QtCore
Definition qfile.h:93
\inmodule QtGui
Definition qimage.h:37
qsizetype bytesPerLine() const
Returns the number of bytes per image scanline.
Definition qimage.cpp:1560
qsizetype sizeInBytes() const
Definition qimage.cpp:1548
uchar * bits()
Returns a pointer to the first pixel data.
Definition qimage.cpp:1698
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
Definition qmatrix4x4.h:147
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
Definition qobject.cpp:1643
\inmodule QtGui
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
void setSubtitleText(const QString &subtitleText)
virtual void setVideoFrame(const QVideoFrame &frame)
@ Immutable
Definition qrhi.h:849
@ Dynamic
Definition qrhi.h:851
@ VertexBuffer
Definition qrhi.h:855
@ UniformBuffer
Definition qrhi.h:857
\inmodule QtGui
Definition qrhi.h:1651
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
Definition qrhi.h:1680
\inmodule QtGui
\variable QRhiGles2InitParams::format
\inmodule QtGui
Definition qrhi.h:1142
\inmodule QtGui
Definition qrhi.h:1731
void uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Immutable or QRhiBuf...
Definition qrhi.cpp:9011
@ ClampToEdge
Definition qrhi.h:1040
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
Definition qrhi.cpp:5640
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
Definition qrhi.cpp:5526
\inmodule QtGui
Definition qrhi.h:1214
\inmodule QtGui
Definition qrhi.h:895
@ RenderTarget
Definition qrhi.h:898
@ ExternalOES
Definition qrhi.h:906
\inmodule QtGui
Definition qrhi.h:321
void setBindings(std::initializer_list< QRhiVertexInputBinding > list)
Sets the bindings from the specified list.
Definition qrhi.h:325
void setAttributes(std::initializer_list< QRhiVertexInputAttribute > list)
Sets the attributes from the specified list.
Definition qrhi.h:337
std::shared_ptr< QRhi > m_guardRhi
QRhiWithThreadGuard(std::shared_ptr< QRhi > r, std::shared_ptr< AndroidTextureThread > t)
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Definition qrhi.cpp:10508
QRhiShaderResourceBindings * newShaderResourceBindings()
Definition qrhi.cpp:10489
@ OpenGLES2
Definition qrhi.h:1809
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
Definition qrhi.cpp:10665
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
Definition qrhi.cpp:10682
QRhiGraphicsPipeline * newGraphicsPipeline()
Definition qrhi.cpp:10466
static QRhi * create(Implementation impl, QRhiInitParams *params, Flags flags={}, QRhiNativeHandles *importDevice=nullptr)
Definition qrhi.cpp:8491
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition qrhi.cpp:10562
const QRhiNativeHandles * nativeHandles()
Definition qrhi.cpp:10137
@ FrameOpSuccess
Definition qrhi.h:1825
\inmodule QtGui
Definition qshader.h:81
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
Definition qshader.cpp:540
bool isValid() const
Definition qshader.cpp:343
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void start(Priority=InheritPriority)
Definition qthread.cpp:996
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
Definition qthread.cpp:1023
void quit()
Definition qthread.cpp:1008
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
MapMode
Enumerates how a video buffer's data is mapped to system memory.
Definition qvideoframe.h:37
The QVideoSink class represents a generic sink for video data.
Definition qvideosink.h:22
void setVideoFrame(const QVideoFrame &frame)
Sets the current video frame.
QPlatformVideoSink * platformVideoSink() const
QRhi * rhi() const
Returns the QRhi instance being used to create texture data in the video frames.
TextureCopy(QRhi *rhi, QRhiTexture *externalTex)
std::unique_ptr< QRhiTexture > copyExternalTexture(QSize size, const QMatrix4x4 &externalTexMatrix)
EGLContext ctx
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
@ BlockingQueuedConnection
static void * context
static QMatrix4x4 extTransformMatrix(AndroidSurfaceTexture *surfaceTexture)
static std::unique_ptr< QRhiGraphicsPipeline > newGraphicsPipeline(QRhi *rhi, QRhiShaderResourceBindings *shaderResourceBindings, QRhiRenderPassDescriptor *renderPassDescriptor, QShader vertexShader, QShader fragmentShader)
static const float g_quad[]
static QDBusError::ErrorType get(const char *name)
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
GLuint64 GLenum void * handle
GLenum mode
const GLfloat * m
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLfloat GLfloat f
GLenum GLuint buffer
GLuint name
void ** params
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei GLenum GLboolean sink
GLfloat GLfloat p
[1]
static QAbstractVideoBuffer::MapData mapData(const camera_frame_nv12_t &frame, unsigned char *baseAddress)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
#define gp
#define Q_OBJECT
#define slots
#define signals
#define emit
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
QImage qImageFromVideoFrame(const QVideoFrame &frame, QtVideo::Rotation rotation, bool mirrorX, bool mirrorY)
if(qFloatDistance(a, b)<(1<< 7))
[0]
QFrame frame
[0]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...