winrt: Fix crash during certain video operations
The abstract video buffer pointer was being reused and (improperly) deleted when its reference count went to zero. As QVideoFrame utilizes an explicitly shared pointer which also tracks the video buffer, simply reuse the QVideoFrame instance instead. Task-number: QTBUG-47373 Change-Id: Idadae205cb520a0a1d752aa20256c0567b3be699 Reviewed-by: Andrew Knight <andrew.knight@intopalo.com>
This commit is contained in:
@@ -125,21 +125,13 @@ Q_GLOBAL_STATIC(QWinRTVideoRendererControlGlobal, g)
|
|||||||
class QWinRTVideoBuffer : public QAbstractVideoBuffer, public QOpenGLTexture
|
class QWinRTVideoBuffer : public QAbstractVideoBuffer, public QOpenGLTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QWinRTVideoBuffer()
|
QWinRTVideoBuffer(const QSize &size, TextureFormat format)
|
||||||
: QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle)
|
: QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle)
|
||||||
, QOpenGLTexture(QOpenGLTexture::Target2D)
|
, QOpenGLTexture(QOpenGLTexture::Target2D)
|
||||||
{
|
{
|
||||||
}
|
setSize(size.width(), size.height());
|
||||||
|
setFormat(format);
|
||||||
void addRef()
|
create();
|
||||||
{
|
|
||||||
refCount.ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
void release() Q_DECL_OVERRIDE
|
|
||||||
{
|
|
||||||
if (!refCount.deref())
|
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapMode mapMode() const Q_DECL_OVERRIDE
|
MapMode mapMode() const Q_DECL_OVERRIDE
|
||||||
@@ -163,9 +155,6 @@ public:
|
|||||||
{
|
{
|
||||||
return QVariant::fromValue(textureId());
|
return QVariant::fromValue(textureId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
QAtomicInt refCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DirtyState {
|
enum DirtyState {
|
||||||
@@ -189,7 +178,7 @@ public:
|
|||||||
EGLConfig eglConfig;
|
EGLConfig eglConfig;
|
||||||
EGLSurface eglSurface;
|
EGLSurface eglSurface;
|
||||||
|
|
||||||
QWinRTVideoBuffer *videoBuffer;
|
QVideoFrame presentFrame;
|
||||||
|
|
||||||
QThread renderThread;
|
QThread renderThread;
|
||||||
bool active;
|
bool active;
|
||||||
@@ -224,8 +213,6 @@ QWinRTAbstractVideoRendererControl::QWinRTAbstractVideoRendererControl(const QSi
|
|||||||
d->eglSurface = EGL_NO_SURFACE;
|
d->eglSurface = EGL_NO_SURFACE;
|
||||||
d->active = false;
|
d->active = false;
|
||||||
|
|
||||||
d->videoBuffer = new QWinRTVideoBuffer;
|
|
||||||
|
|
||||||
connect(&d->renderThread, &QThread::started,
|
connect(&d->renderThread, &QThread::started,
|
||||||
this, &QWinRTAbstractVideoRendererControl::syncAndRender,
|
this, &QWinRTAbstractVideoRendererControl::syncAndRender,
|
||||||
Qt::DirectConnection);
|
Qt::DirectConnection);
|
||||||
@@ -390,23 +377,19 @@ void QWinRTAbstractVideoRendererControl::present()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->videoBuffer->setFormat(QOpenGLTexture::RGBAFormat);
|
QWinRTVideoBuffer *videoBuffer = new QWinRTVideoBuffer(d->format.frameSize(), QOpenGLTexture::RGBAFormat);
|
||||||
d->videoBuffer->setSize(d->format.frameWidth(), d->format.frameHeight());
|
d->presentFrame = QVideoFrame(videoBuffer, d->format.frameSize(), d->format.pixelFormat());
|
||||||
if (!d->videoBuffer->isCreated())
|
|
||||||
d->videoBuffer->create();
|
|
||||||
|
|
||||||
// bind the pbuffer surface to the texture
|
// bind the pbuffer surface to the texture
|
||||||
d->videoBuffer->bind();
|
videoBuffer->bind();
|
||||||
eglBindTexImage(d->eglDisplay, d->eglSurface, EGL_BACK_BUFFER);
|
eglBindTexImage(d->eglDisplay, d->eglSurface, EGL_BACK_BUFFER);
|
||||||
static_cast<QOpenGLTexture *>(d->videoBuffer)->release();
|
static_cast<QOpenGLTexture *>(videoBuffer)->release();
|
||||||
|
|
||||||
d->dirtyState = NotDirty;
|
d->dirtyState = NotDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present the frame
|
// Present the frame
|
||||||
d->videoBuffer->addRef();
|
d->surface->present(d->presentFrame);
|
||||||
QVideoFrame frame(d->videoBuffer, d->format.frameSize(), d->format.pixelFormat());
|
|
||||||
d->surface->present(frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
Reference in New Issue
Block a user