From 2079605239b871f8a927ebdeb6fbea5655dcb1b8 Mon Sep 17 00:00:00 2001 From: Lauri Laanmets Date: Wed, 14 Dec 2022 11:44:21 +0200 Subject: Correctly finish, clear and delete AndroidTextureThread 'QAndroidTextureVideoOutput' destructor waited for 'm_surfaceThread' to be finished but seems that this thread was nowhere requested to finish. In addition, 'AndroidTextureThread' created 'std::unique_ptr m_rhi;' in it's own thread but didn't reset it. Thus, deleting the whole 'AndroidTextureThread' from another thread, started deleting it and failed. Task-number: QTBUG-109168 Change-Id: I9e12228c579457710c4fe5d8185bffabf9f3755a Reviewed-by: Samuel Mira Reviewed-by: Artem Dyomin Reviewed-by: Lars Knoll (cherry picked from commit d4e02d9efd6e8e41aa1a83c0f3d6534d138e7ae3) Reviewed-by: Qt Cherry-pick Bot --- .../android/common/qandroidvideooutput.cpp | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/plugins/multimedia/android/common/qandroidvideooutput.cpp') diff --git a/src/plugins/multimedia/android/common/qandroidvideooutput.cpp b/src/plugins/multimedia/android/common/qandroidvideooutput.cpp index 38029c479..7cd0c9242 100644 --- a/src/plugins/multimedia/android/common/qandroidvideooutput.cpp +++ b/src/plugins/multimedia/android/common/qandroidvideooutput.cpp @@ -267,12 +267,15 @@ public: public slots: void onFrameAvailable() { - m_surfaceTexture->updateTexImage(); - auto matrix = extTransformMatrix(m_surfaceTexture.get()); - auto tex = m_textureCopy->copyExternalTexture(m_size, matrix); - auto *buffer = new AndroidTextureVideoBuffer(m_rhi.get(), std::move(tex), m_size); - QVideoFrame frame(buffer, QVideoFrameFormat(m_size, QVideoFrameFormat::Format_RGBA8888)); - emit newFrame(frame); + // Check if 'm_surfaceTexture' is not reset because there can be pending frames in queue. + if (m_surfaceTexture) { + m_surfaceTexture->updateTexImage(); + auto matrix = extTransformMatrix(m_surfaceTexture.get()); + auto tex = m_textureCopy->copyExternalTexture(m_size, matrix); + auto *buffer = new AndroidTextureVideoBuffer(m_rhi.get(), std::move(tex), m_size); + QVideoFrame frame(buffer, QVideoFrameFormat(m_size, QVideoFrameFormat::Format_RGBA8888)); + emit newFrame(frame); + } } void clearFrame() { emit newFrame({}); } @@ -284,6 +287,7 @@ public slots: m_surfaceTexture.reset(); m_texture.reset(); m_textureCopy.reset(); + m_rhi.reset(); } AndroidSurfaceTexture *createSurfaceTexture(QRhi *rhi) @@ -328,8 +332,8 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QVideoSink *sink, QObject : QAndroidVideoOutput(parent) , m_sink(sink) { - if (!m_sink || !m_sink->rhi()) { - qDebug() << "Cannot create QAndroidTextureVideoOutput without a sink and a rhi"; + if (!m_sink) { + qDebug() << "Cannot create QAndroidTextureVideoOutput without a sink."; m_surfaceThread = nullptr; return; } @@ -344,8 +348,9 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QVideoSink *sink, QObject QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput() { - if (m_surfaceThread) - m_surfaceThread->wait(); + QMetaObject::invokeMethod(m_surfaceThread.get(), &AndroidTextureThread::clearSurfaceTexture); + m_surfaceThread->quit(); + m_surfaceThread->wait(); } void QAndroidTextureVideoOutput::setSubtitle(const QString &subtitle) -- cgit v1.2.3