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>
32 return plane == 0 ? m_tex.get() :
nullptr;
36 std::unique_ptr<QRhiTexture> m_tex;
45 , m_tex(
std::move(tex))
60 return std::make_unique<QAndroidVideoFrameTextures>(
rhi, m_size, m_tex->nativeTexture().object);
65 std::unique_ptr<QRhiTexture> m_tex;
107 -1.f, -1.f, 0.f, 0.f,
128 m_vertexBuffer->create();
131 m_uniformBuffer->create();
144 m_vertexShader = getShader(
QStringLiteral(
":/qt-project.org/multimedia/shaders/externalsampler.vert.qsb"));
146 m_fragmentShader = getShader(
QStringLiteral(
":/qt-project.org/multimedia/shaders/externalsampler.frag.qsb"));
153 QRhi *m_rhi =
nullptr;
154 std::unique_ptr<QRhiBuffer> m_vertexBuffer;
155 std::unique_ptr<QRhiBuffer> m_uniformBuffer;
156 std::unique_ptr<QRhiSampler> m_sampler;
157 std::unique_ptr<QRhiShaderResourceBindings> m_srb;
170 gp->setShaderStages({
176 { 4 *
sizeof(float) }
182 gp->setVertexInputLayout(inputLayout);
183 gp->setShaderResourceBindings(shaderResourceBindings);
184 gp->setRenderPassDescriptor(renderPassDescriptor);
193 if (!tex->create()) {
194 qWarning(
"Failed to create frame texture");
199 std::unique_ptr<QRhiRenderPassDescriptor> renderPassDescriptor(renderTarget->newCompatibleRenderPassDescriptor());
200 renderTarget->setRenderPassDescriptor(renderPassDescriptor.get());
201 renderTarget->create();
207 char *
p = m_uniformBuffer->beginFullDynamicBufferUpdateForCurrentFrame();
209 memcpy(
p + 64, externalTexMatrix.constData(), 64);
210 float opacity = 1.0f;
211 memcpy(
p + 64 + 64, &opacity, 4);
212 m_uniformBuffer->endFullDynamicBufferUpdateForCurrentFrame();
214 auto graphicsPipeline =
newGraphicsPipeline(m_rhi, m_srb.get(), renderPassDescriptor.get(),
215 m_vertexShader, m_fragmentShader);
224 cb->setGraphicsPipeline(graphicsPipeline.get());
225 cb->setViewport({0, 0, float(
size.width()), float(
size.height())});
226 cb->setShaderResources(m_srb.get());
227 cb->setVertexInput(0, 1, &vbufBinding);
230 m_rhi->endOffscreenFrame();
245 static const QMatrix4x4 flipV(1.0f, 0.0f, 0.0f, 0.0f,
246 0.0f, -1.0f, 0.0f, 1.0f,
247 0.0f, 0.0f, 1.0f, 0.0f,
248 0.0f, 0.0f, 0.0f, 1.0f);
263 params.fallbackSurface = QRhiGles2InitParams::newFallbackSurface();
271 if (m_surfaceTexture) {
272 m_surfaceTexture->updateTexImage();
274 auto tex = m_textureCopy->copyExternalTexture(m_size,
matrix);
287 m_surfaceTexture.reset();
289 m_textureCopy.reset();
295 if (m_surfaceTexture)
296 return m_surfaceTexture.get();
305 m_surfaceTexture = std::make_unique<AndroidSurfaceTexture>(m_texture->nativeTexture().object);
306 if (m_surfaceTexture->surfaceTexture()) {
310 m_textureCopy = std::make_unique<TextureCopy>(m_rhi.get(), m_texture.get());
314 m_surfaceTexture.reset();
317 return m_surfaceTexture.get();
324 std::unique_ptr<QRhi> m_rhi;
325 std::unique_ptr<AndroidSurfaceTexture> m_surfaceTexture;
326 std::unique_ptr<QRhiTexture> m_texture;
327 std::unique_ptr<TextureCopy> m_textureCopy;
336 qDebug() <<
"Cannot create QAndroidTextureVideoOutput without a sink.";
337 m_surfaceThread =
nullptr;
341 m_surfaceThread = std::make_unique<AndroidTextureThread>();
343 this, &QAndroidTextureVideoOutput::newFrame);
345 m_surfaceThread->start();
346 m_surfaceThread->moveToThread(m_surfaceThread.get());
353 m_surfaceThread->quit();
354 m_surfaceThread->wait();
368 return m_sink->
rhi() && m_surfaceCreatedWithoutRhi;
378 auto rhi = m_sink->rhi();
380 m_surfaceCreatedWithoutRhi = true;
382 else if (m_surfaceCreatedWithoutRhi) {
383 m_surfaceThread->clearSurfaceTexture();
384 m_surfaceCreatedWithoutRhi =
false;
386 surface = m_surfaceThread->createSurfaceTexture(rhi);
394 if (m_nativeSize ==
size)
399 [&](){ m_surfaceThread->setFrameSize(size); },
424#include "qandroidvideooutput.moc"
425#include "moc_qandroidvideooutput_p.cpp"
QMatrix4x4 getTransformMatrix()
void newFrame(const QVideoFrame &)
AndroidSurfaceTexture * createSurfaceTexture(QRhi *rhi)
void initRhi(QOpenGLContext *context)
void clearSurfaceTexture()
void setFrameSize(QSize size)
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(QRhi *rhi, 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
AndroidSurfaceTexture * surfaceTexture() override
QVideoSink * surface() const
bool shouldTextureBeUpdated() const
~QAndroidTextureVideoOutput() override
QAndroidVideoFrameTextures(QRhi *rhi, QSize size, quint64 handle)
QRhiTexture * texture(uint plane) const override
qsizetype bytesPerLine() const
Returns the number of bytes per image scanline.
qsizetype sizeInBytes() const
uchar * bits()
Returns a pointer to the first pixel data.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
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.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
\variable QRhiGles2InitParams::format
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...
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
QRhiShaderResourceBindings * newShaderResourceBindings()
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
QRhiGraphicsPipeline * newGraphicsPipeline()
static QRhi * create(Implementation impl, QRhiInitParams *params, Flags flags={}, QRhiNativeHandles *importDevice=nullptr)
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
const QRhiNativeHandles * nativeHandles()
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
\macro QT_RESTRICTED_CAST_FROM_ASCII
The QVideoFrame class represents a frame of video data.
MapMode
Enumerates how a video buffer's data is mapped to system memory.
The QVideoSink class represents a generic sink for video data.
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)
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
@ BlockingQueuedConnection
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[]
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum GLboolean sink
static QAbstractVideoBuffer::MapData mapData(const camera_frame_nv12_t &frame, unsigned char *baseAddress)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
unsigned long long quint64
QImage qImageFromVideoFrame(const QVideoFrame &frame, QVideoFrame::RotationAngle rotation, bool mirrorX, bool mirrorY)
if(qFloatDistance(a, b)<(1<< 7))
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent