diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp
index f462a28d56e4d19f86d8a02ca99f016cece559ad..2010ec9e018eba7fbb24a3408c73fd5639947c46 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.cpp
+++ b/src/plugins/android/src/common/qandroidvideooutput.cpp
@@ -60,6 +60,22 @@ static const GLfloat g_texture_data[] = {
     0.f, 1.f
 };
 
+void OpenGLResourcesDeleter::deleteTextureHelper(quint32 id)
+{
+    if (id != 0)
+        glDeleteTextures(1, &id);
+}
+
+void OpenGLResourcesDeleter::deleteFboHelper(void *fbo)
+{
+    delete reinterpret_cast<QOpenGLFramebufferObject *>(fbo);
+}
+
+void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog)
+{
+    delete reinterpret_cast<QOpenGLShaderProgram *>(prog);
+}
+
 
 class AndroidTextureVideoBuffer : public QAbstractVideoBuffer
 {
@@ -124,40 +140,6 @@ private:
     QImage m_image;
 };
 
-
-class OpenGLResourcesDeleter : public QObject
-{
-public:
-    OpenGLResourcesDeleter()
-        : m_textureID(0)
-        , m_fbo(0)
-        , m_program(0)
-    { }
-
-    ~OpenGLResourcesDeleter()
-    {
-        glDeleteTextures(1, &m_textureID);
-        delete m_fbo;
-        delete m_program;
-    }
-
-    void setTexture(quint32 id) {
-        if (m_textureID)
-            glDeleteTextures(1, &m_textureID);
-
-        m_textureID = id;
-    }
-
-    void setFbo(QOpenGLFramebufferObject *fbo) { m_fbo = fbo; }
-    void setShaderProgram(QOpenGLShaderProgram *prog) { m_program = prog; }
-
-private:
-    quint32 m_textureID;
-    QOpenGLFramebufferObject *m_fbo;
-    QOpenGLShaderProgram *m_program;
-};
-
-
 QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent)
     : QAndroidVideoOutput(parent)
     , m_surface(0)
@@ -165,7 +147,6 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent)
     , m_externalTex(0)
     , m_fbo(0)
     , m_program(0)
-    , m_glDeleter(0)
     , m_surfaceTextureCanAttachToContext(QtAndroidPrivate::androidSdkVersion() >= 16)
 {
 
@@ -175,8 +156,12 @@ QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput()
 {
     clearSurfaceTexture();
 
-    if (m_glDeleter)
+    if (!m_glDeleter.isNull()) { // Make sure all of these are deleted on the render thread.
+        m_glDeleter->deleteFbo(m_fbo);
+        m_glDeleter->deleteShaderProgram(m_program);
+        m_glDeleter->deleteTexture(m_externalTex);
         m_glDeleter->deleteLater();
+    }
 }
 
 QAbstractVideoSurface *QAndroidTextureVideoOutput::surface() const
@@ -223,8 +208,7 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture()
         // for the GL render thread to call us back to do it.
         if (QOpenGLContext::currentContext()) {
             glGenTextures(1, &m_externalTex);
-            m_glDeleter = new OpenGLResourcesDeleter;
-            m_glDeleter->setTexture(m_externalTex);
+            m_glDeleter.reset(new OpenGLResourcesDeleter);
         } else if (!m_externalTex) {
             return false;
         }
@@ -239,10 +223,9 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture()
     } else {
         delete m_surfaceTexture;
         m_surfaceTexture = 0;
-        if (m_glDeleter)
-            m_glDeleter->deleteLater();
+        if (!m_glDeleter.isNull())
+            m_glDeleter->deleteTexture(m_externalTex);
         m_externalTex = 0;
-        m_glDeleter = 0;
     }
 
     return m_surfaceTexture != 0;
@@ -257,8 +240,14 @@ void QAndroidTextureVideoOutput::clearSurfaceTexture()
     }
 
     // Also reset the attached OpenGL texture
-    if (m_surfaceTextureCanAttachToContext)
+    // Note: The Android SurfaceTexture class does not release the texture on deletion,
+    // only if detachFromGLContext() called (API level >= 16), so we'll do it manually,
+    // on the render thread.
+    if (m_surfaceTextureCanAttachToContext) {
+        if (!m_glDeleter.isNull())
+            m_glDeleter->deleteTexture(m_externalTex);
         m_externalTex = 0;
+    }
 }
 
 AndroidSurfaceTexture *QAndroidTextureVideoOutput::surfaceTexture()
@@ -388,19 +377,17 @@ void QAndroidTextureVideoOutput::createGLResources()
     Q_ASSERT(QOpenGLContext::currentContext() != NULL);
 
     if (!m_glDeleter)
-        m_glDeleter = new OpenGLResourcesDeleter;
+        m_glDeleter.reset(new OpenGLResourcesDeleter);
 
     if (m_surfaceTextureCanAttachToContext && !m_externalTex) {
         m_surfaceTexture->detachFromGLContext();
         glGenTextures(1, &m_externalTex);
         m_surfaceTexture->attachToGLContext(m_externalTex);
-        m_glDeleter->setTexture(m_externalTex);
     }
 
     if (!m_fbo || m_fbo->size() != m_nativeSize) {
         delete m_fbo;
         m_fbo = new QOpenGLFramebufferObject(m_nativeSize);
-        m_glDeleter->setFbo(m_fbo);
     }
 
     if (!m_program) {
@@ -431,8 +418,6 @@ void QAndroidTextureVideoOutput::createGLResources()
         m_program->bindAttributeLocation("vertexCoordsArray", 0);
         m_program->bindAttributeLocation("textureCoordArray", 1);
         m_program->link();
-
-        m_glDeleter->setShaderProgram(m_program);
     }
 }
 
@@ -442,8 +427,7 @@ void QAndroidTextureVideoOutput::customEvent(QEvent *e)
         // This is running in the render thread (OpenGL enabled)
         if (!m_surfaceTextureCanAttachToContext && !m_externalTex) {
             glGenTextures(1, &m_externalTex);
-            m_glDeleter = new OpenGLResourcesDeleter; // will cleanup GL resources in the correct thread
-            m_glDeleter->setTexture(m_externalTex);
+            m_glDeleter.reset(new OpenGLResourcesDeleter); // We'll use this to cleanup GL resources in the correct thread
             emit readyChanged(true);
         }
     }
diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h
index 0068a580900928f6ce1ba142c5ba930974af318c..09bd5d87e235b669c960bf84d5fd727323aa1a34 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.h
+++ b/src/plugins/android/src/common/qandroidvideooutput.h
@@ -44,7 +44,6 @@ class AndroidSurfaceTexture;
 class AndroidSurfaceHolder;
 class QOpenGLFramebufferObject;
 class QOpenGLShaderProgram;
-class OpenGLResourcesDeleter;
 class QAbstractVideoSurface;
 
 class QAndroidVideoOutput : public QObject
@@ -69,6 +68,19 @@ protected:
     QAndroidVideoOutput(QObject *parent) : QObject(parent) { }
 };
 
+class OpenGLResourcesDeleter : public QObject
+{
+    Q_OBJECT
+public:
+    void deleteTexture(quint32 id) { QMetaObject::invokeMethod(this, "deleteTextureHelper", Qt::AutoConnection, Q_ARG(quint32, id)); }
+    void deleteFbo(QOpenGLFramebufferObject *fbo) { QMetaObject::invokeMethod(this, "deleteFboHelper", Qt::AutoConnection, Q_ARG(void *, fbo)); }
+    void deleteShaderProgram(QOpenGLShaderProgram *prog) { QMetaObject::invokeMethod(this, "deleteShaderProgramHelper", Qt::AutoConnection, Q_ARG(void *, prog)); }
+
+private:
+    Q_INVOKABLE void deleteTextureHelper(quint32 id);
+    Q_INVOKABLE void deleteFboHelper(void *fbo);
+    Q_INVOKABLE void deleteShaderProgramHelper(void *prog);
+};
 
 class QAndroidTextureVideoOutput : public QAndroidVideoOutput
 {
@@ -108,7 +120,7 @@ private:
     quint32 m_externalTex;
     QOpenGLFramebufferObject *m_fbo;
     QOpenGLShaderProgram *m_program;
-    OpenGLResourcesDeleter *m_glDeleter;
+    QScopedPointer<OpenGLResourcesDeleter, QScopedPointerDeleteLater> m_glDeleter;
 
     bool m_surfaceTextureCanAttachToContext;
 
diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
index bc7187e9cf532a20f23eb6fed4b620f8ee83f616..cd6d41d842faf71c5af04ae6c1e1c003ee449599 100644
--- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
@@ -56,7 +56,7 @@ static void notifyFrameAvailable(JNIEnv* , jobject, jlong id)
         Q_EMIT obj->frameAvailable();
 }
 
-AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName)
+AndroidSurfaceTexture::AndroidSurfaceTexture(quint32 texName)
     : QObject()
 {
     Q_STATIC_ASSERT(sizeof (jlong) >= sizeof (void *));
@@ -157,7 +157,7 @@ jobject AndroidSurfaceTexture::surfaceHolder()
     return m_surfaceHolder.object();
 }
 
-void AndroidSurfaceTexture::attachToGLContext(int texName)
+void AndroidSurfaceTexture::attachToGLContext(quint32 texName)
 {
     if (QtAndroidPrivate::androidSdkVersion() < 16 || !m_surfaceTexture.isValid())
         return;
diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h
index 3c41bf51d64b65620a898faa88254c0261af3f40..1b82ad20e8eb295b1e4f44b17400f9af11eec2dc 100644
--- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h
+++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h
@@ -45,7 +45,7 @@ class AndroidSurfaceTexture : public QObject
 {
     Q_OBJECT
 public:
-    explicit AndroidSurfaceTexture(unsigned int texName);
+    explicit AndroidSurfaceTexture(quint32 texName);
     ~AndroidSurfaceTexture();
 
     jobject surfaceTexture();
@@ -57,7 +57,7 @@ public:
     void release(); // API level 14
     void updateTexImage();
 
-    void attachToGLContext(int texName); // API level 16
+    void attachToGLContext(quint32 texName); // API level 16
     void detachFromGLContext(); // API level 16
 
     static bool initJNI(JNIEnv *env);