diff --git a/examples/multimedia/audioinput/audioinput.h b/examples/multimedia/audioinput/audioinput.h
index d3a949daa3298f9aba6629c41369d5bc0f9590a2..b6deb361c86685ff552484018ea53d84cbabad22 100644
--- a/examples/multimedia/audioinput/audioinput.h
+++ b/examples/multimedia/audioinput/audioinput.h
@@ -64,8 +64,8 @@ public:
 
     qreal level() const { return m_level; }
 
-    qint64 readData(char *data, qint64 maxlen);
-    qint64 writeData(const char *data, qint64 len);
+    qint64 readData(char *data, qint64 maxlen) override;
+    qint64 writeData(const char *data, qint64 len) override;
 
 private:
     const QAudioFormat m_format;
@@ -87,7 +87,7 @@ public:
     void setLevel(qreal value);
 
 protected:
-    void paintEvent(QPaintEvent *event);
+    void paintEvent(QPaintEvent *event) override;
 
 private:
     qreal m_level;
diff --git a/examples/multimedia/audiooutput/audiooutput.h b/examples/multimedia/audiooutput/audiooutput.h
index 7c245420940fe069844a4e017fbfda4cbe76fabd..d5c2b4cc272e983de30a1c70f59b6ecd8b9ef8e3 100644
--- a/examples/multimedia/audiooutput/audiooutput.h
+++ b/examples/multimedia/audiooutput/audiooutput.h
@@ -65,9 +65,9 @@ public:
     void start();
     void stop();
 
-    qint64 readData(char *data, qint64 maxlen);
-    qint64 writeData(const char *data, qint64 len);
-    qint64 bytesAvailable() const;
+    qint64 readData(char *data, qint64 maxlen) override;
+    qint64 writeData(const char *data, qint64 len) override;
+    qint64 bytesAvailable() const override;
 
 private:
     void generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate);
diff --git a/examples/multimedia/audiorecorder/qaudiolevel.h b/examples/multimedia/audiorecorder/qaudiolevel.h
index 5c9c840005aff6965b169c5884f814d87ca3e81f..f8e563adc3d113308af143b4f276ffcf61e44f7b 100644
--- a/examples/multimedia/audiorecorder/qaudiolevel.h
+++ b/examples/multimedia/audiorecorder/qaudiolevel.h
@@ -53,7 +53,7 @@ public:
     void setLevel(qreal level);
 
 protected:
-    void paintEvent(QPaintEvent *event);
+    void paintEvent(QPaintEvent *event) override;
 
 private:
     qreal m_level;
diff --git a/examples/multimedia/spectrum/app/levelmeter.h b/examples/multimedia/spectrum/app/levelmeter.h
index f44da308f8e0b631a522c6ce82f225250da34733..075e9af960d9124cfb1bfee0b74ed6cc9af80e2c 100644
--- a/examples/multimedia/spectrum/app/levelmeter.h
+++ b/examples/multimedia/spectrum/app/levelmeter.h
@@ -57,7 +57,7 @@ public:
     explicit LevelMeter(QWidget *parent = 0);
     ~LevelMeter();
 
-    void paintEvent(QPaintEvent *event);
+    void paintEvent(QPaintEvent *event) override;
 
 public slots:
     void reset();
diff --git a/examples/multimedia/spectrum/app/mainwidget.h b/examples/multimedia/spectrum/app/mainwidget.h
index 449a021c42cc932468ab15b0e891ca5209904943..c8bbce022ce6b8eb55b61a97b85a323a5d02fe5b 100644
--- a/examples/multimedia/spectrum/app/mainwidget.h
+++ b/examples/multimedia/spectrum/app/mainwidget.h
@@ -75,7 +75,7 @@ public:
     ~MainWidget();
 
     // QObject
-    void timerEvent(QTimerEvent *event);
+    void timerEvent(QTimerEvent *event) override;
 
 public slots:
     void stateChanged(QAudio::Mode mode, QAudio::State state);
diff --git a/examples/multimedia/spectrum/app/progressbar.h b/examples/multimedia/spectrum/app/progressbar.h
index 6b8032541f24de1233a3cb12607e28b131166745..f6fed3f66f77a662172246f09c72b46046f51dc2 100644
--- a/examples/multimedia/spectrum/app/progressbar.h
+++ b/examples/multimedia/spectrum/app/progressbar.h
@@ -56,7 +56,7 @@ public:
     ~ProgressBar();
 
     void reset();
-    void paintEvent(QPaintEvent *event);
+    void paintEvent(QPaintEvent *event) override;
 
 public slots:
     void bufferLengthChanged(qint64 length);
diff --git a/examples/multimedia/spectrum/app/spectrograph.h b/examples/multimedia/spectrum/app/spectrograph.h
index c75e3141656dc4088760ad5e36574f833dd77774..64182feec7bcaae759893adba92328670cdc79d0 100644
--- a/examples/multimedia/spectrum/app/spectrograph.h
+++ b/examples/multimedia/spectrum/app/spectrograph.h
@@ -60,11 +60,11 @@ public:
     void setParams(int numBars, qreal lowFreq, qreal highFreq);
 
     // QObject
-    void timerEvent(QTimerEvent *event);
+    void timerEvent(QTimerEvent *event) override;
 
     // QWidget
-    void paintEvent(QPaintEvent *event);
-    void mousePressEvent(QMouseEvent *event);
+    void paintEvent(QPaintEvent *event) override;
+    void mousePressEvent(QMouseEvent *event) override;
 
 signals:
     void infoMessage(const QString &message, int intervalMs);
diff --git a/examples/multimedia/spectrum/app/waveform.h b/examples/multimedia/spectrum/app/waveform.h
index b49416b20b5e31b434f4a936f424fed4451fcf86..213461e929443261bb769966ca366749b5f78591 100644
--- a/examples/multimedia/spectrum/app/waveform.h
+++ b/examples/multimedia/spectrum/app/waveform.h
@@ -64,8 +64,8 @@ public:
     ~Waveform();
 
     // QWidget
-    void paintEvent(QPaintEvent *event);
-    void resizeEvent(QResizeEvent *event);
+    void paintEvent(QPaintEvent *event) override;
+    void resizeEvent(QResizeEvent *event) override;
 
     void initialize(const QAudioFormat &format, qint64 audioBufferSize, qint64 windowDurationUs);
     void reset();
diff --git a/examples/multimediawidgets/camera/camera.h b/examples/multimediawidgets/camera/camera.h
index daef427dd1f5949c075528a4353b4414cfb5732e..3db1347b6888995c47057263ccecc083b1190bd7 100644
--- a/examples/multimediawidgets/camera/camera.h
+++ b/examples/multimediawidgets/camera/camera.h
@@ -100,9 +100,9 @@ private slots:
     void imageSaved(int id, const QString &fileName);
 
 protected:
-    void keyPressEvent(QKeyEvent *event);
-    void keyReleaseEvent(QKeyEvent *event);
-    void closeEvent(QCloseEvent *event);
+    void keyPressEvent(QKeyEvent *event) override;
+    void keyReleaseEvent(QKeyEvent *event) override;
+    void closeEvent(QCloseEvent *event) override;
 
 private:
     Ui::Camera *ui;
diff --git a/examples/multimediawidgets/camera/imagesettings.h b/examples/multimediawidgets/camera/imagesettings.h
index bdb65e2a7d6026a512d48d803f380e85fbf52303..31afbd2f57dcb674a78ef9e94fed6cb6174fb769 100644
--- a/examples/multimediawidgets/camera/imagesettings.h
+++ b/examples/multimediawidgets/camera/imagesettings.h
@@ -69,7 +69,7 @@ public:
     void setFormat(const QString &format);
 
 protected:
-    void changeEvent(QEvent *e);
+    void changeEvent(QEvent *e) override;
 
 private:
     QVariant boxValue(const QComboBox *box) const;
diff --git a/examples/multimediawidgets/camera/videosettings.h b/examples/multimediawidgets/camera/videosettings.h
index a4e01fd4c2e422a029de1a754e989c7cd2838751..c4a05faceb74ad54e3adec63f10359e5a58c2996 100644
--- a/examples/multimediawidgets/camera/videosettings.h
+++ b/examples/multimediawidgets/camera/videosettings.h
@@ -69,7 +69,7 @@ public:
     void setFormat(const QString &format);
 
 protected:
-    void changeEvent(QEvent *e);
+    void changeEvent(QEvent *e) override;
 
 private:
     QVariant boxValue(const QComboBox*) const;
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h
index 062dd1db8e8723c0ec54138c1ea04b573d1c7036..6b971512e600fdd109bf2955a7525f6696fdaf63 100644
--- a/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h
@@ -55,16 +55,16 @@ public:
     explicit VideoItem(QGraphicsItem *parentItem = 0);
     ~VideoItem();
 
-    QRectF boundingRect() const;
-    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    QRectF boundingRect() const override;
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
 
     //video surface
     QList<QVideoFrame::PixelFormat> supportedPixelFormats(
-            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
+            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const override;
 
-    bool start(const QVideoSurfaceFormat &format);
-    void stop();
-    bool present(const QVideoFrame &frame);
+    bool start(const QVideoSurfaceFormat &format) override;
+    void stop() override;
+    bool present(const QVideoFrame &frame) override;
 
 private:
     QImage::Format imageFormat;
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h
index 5edea4ce3d6f73e972654b4dc303f77445451fb5..1b4b07dd21daee8d0659812c015240711ef53293 100644
--- a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h
@@ -60,7 +60,7 @@ public:
     VideoPlayer(QWidget *parent = 0);
     ~VideoPlayer();
 
-    QSize sizeHint() const { return QSize(800, 600); }
+    QSize sizeHint() const override { return QSize(800, 600); }
 
 public slots:
     void openFile();
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h
index f769f15b802c3e00a2a5eb6a04747bb0a4257d78..b57754643871909871be0da27cff84593324b357 100644
--- a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h
@@ -56,11 +56,11 @@ public:
 
     QAbstractVideoSurface *videoSurface() const { return surface; }
 
-    QSize sizeHint() const;
+    QSize sizeHint() const override;
 
 protected:
-    void paintEvent(QPaintEvent *event);
-    void resizeEvent(QResizeEvent *event);
+    void paintEvent(QPaintEvent *event) override;
+    void resizeEvent(QResizeEvent *event) override;
 
 private:
     VideoWidgetSurface *surface;
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h
index c869dbeb651161fc30dd91d6829490d8e81d4343..41d05b709506492bccaf2a12d7e0d4ec5452f342 100644
--- a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h
@@ -55,13 +55,13 @@ public:
     VideoWidgetSurface(QWidget *widget, QObject *parent = 0);
 
     QList<QVideoFrame::PixelFormat> supportedPixelFormats(
-            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
-    bool isFormatSupported(const QVideoSurfaceFormat &format) const;
+            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const override;
+    bool isFormatSupported(const QVideoSurfaceFormat &format) const override;
 
-    bool start(const QVideoSurfaceFormat &format);
-    void stop();
+    bool start(const QVideoSurfaceFormat &format) override;
+    void stop() override;
 
-    bool present(const QVideoFrame &frame);
+    bool present(const QVideoFrame &frame) override;
 
     QRect videoRect() const { return targetRect; }
     void updateVideoRect();
diff --git a/examples/multimediawidgets/player/histogramwidget.h b/examples/multimediawidgets/player/histogramwidget.h
index f979e87063906cdd69764d18aee1a62185266842..9462b1c84a4fb4a6175ff498bfb451b6229dcf4c 100644
--- a/examples/multimediawidgets/player/histogramwidget.h
+++ b/examples/multimediawidgets/player/histogramwidget.h
@@ -70,7 +70,7 @@ public slots:
     void setHistogram(QVector<qreal> histogram);
 
 protected:
-    void paintEvent(QPaintEvent *event);
+    void paintEvent(QPaintEvent *event) override;
 
 private:
     QVector<qreal> m_histogram;
diff --git a/examples/multimediawidgets/player/playlistmodel.h b/examples/multimediawidgets/player/playlistmodel.h
index 85a1fbef0e617151eeaf88ff4778170da1da086a..960943f1c78a94b9895691332db89dbe0c85e183 100644
--- a/examples/multimediawidgets/player/playlistmodel.h
+++ b/examples/multimediawidgets/player/playlistmodel.h
@@ -60,18 +60,18 @@ public:
 
     PlaylistModel(QObject *parent = 0);
 
-    int rowCount(const QModelIndex &parent = QModelIndex()) const;
-    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
 
-    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
-    QModelIndex parent(const QModelIndex &child) const;
+    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+    QModelIndex parent(const QModelIndex &child) const override;
 
-    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
 
     QMediaPlaylist *playlist() const;
     void setPlaylist(QMediaPlaylist *playlist);
 
-    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
+    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
 
 private slots:
     void beginInsertItems(int start, int end);
diff --git a/examples/multimediawidgets/player/videowidget.h b/examples/multimediawidgets/player/videowidget.h
index 82093c05d4209dbe1553767dbb803bb334220be0..00a27a78b12454345992350d3a0ae064b7443cd1 100644
--- a/examples/multimediawidgets/player/videowidget.h
+++ b/examples/multimediawidgets/player/videowidget.h
@@ -51,9 +51,9 @@ public:
     VideoWidget(QWidget *parent = 0);
 
 protected:
-    void keyPressEvent(QKeyEvent *event);
-    void mouseDoubleClickEvent(QMouseEvent *event);
-    void mousePressEvent(QMouseEvent *event);
+    void keyPressEvent(QKeyEvent *event) override;
+    void mouseDoubleClickEvent(QMouseEvent *event) override;
+    void mousePressEvent(QMouseEvent *event) override;
 };
 
 #endif // VIDEOWIDGET_H
diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.h b/examples/multimediawidgets/videographicsitem/videoplayer.h
index 914c59499897de4ed0c04835e4b31550f6bee827..ffccc9a9cdb0a5b6de672ee4e3d27219be48fd03 100644
--- a/examples/multimediawidgets/videographicsitem/videoplayer.h
+++ b/examples/multimediawidgets/videographicsitem/videoplayer.h
@@ -62,7 +62,7 @@ public:
     void load(const QUrl &url);
     bool isPlayerAvailable() const;
 
-    QSize sizeHint() const Q_DECL_OVERRIDE;
+    QSize sizeHint() const override;
 
 public slots:
     void openFile();
diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp
index 2e2dfc2dbcd1d9be52658624869685f4384284ed..3a38061555b13076761d6d2bbfdfcabd9ae8a533 100644
--- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp
@@ -96,27 +96,44 @@ class PulseDaemon : public QObject
 {
     Q_OBJECT
 public:
-    PulseDaemon(): m_prepared(false)
+    PulseDaemon()
+        : m_prepared(false)
+        , m_lockCount(0)
     {
         prepare();
     }
 
     ~PulseDaemon()
     {
-        if (m_prepared)
+        release();
+    }
+
+    inline void ref()
+    {
+        m_ref.ref();
+        prepare();
+    }
+
+    inline void deref()
+    {
+        if (!m_ref.deref())
             release();
     }
 
     inline void lock()
     {
-        if (m_mainLoop)
-            pa_threaded_mainloop_lock(m_mainLoop);
+        if (m_mainLoop) {
+            if (++m_lockCount == 1)
+                pa_threaded_mainloop_lock(m_mainLoop);
+        }
     }
 
     inline void unlock()
     {
-        if (m_mainLoop)
-            pa_threaded_mainloop_unlock(m_mainLoop);
+        if (m_mainLoop) {
+            if (--m_lockCount == 0)
+                pa_threaded_mainloop_unlock(m_mainLoop);
+        }
     }
 
     inline pa_context *context() const
@@ -141,6 +158,9 @@ private Q_SLOTS:
 
     void prepare()
     {
+        if (m_prepared)
+            return;
+
         m_context = 0;
         m_mainLoop = pa_threaded_mainloop_new();
         if (m_mainLoop == 0) {
@@ -191,8 +211,9 @@ private:
             return;
 
         if (m_context) {
-            pa_context_unref(m_context);
-            m_context = 0;
+            lock();
+            pa_context_disconnect(m_context);
+            unlock();
         }
 
         if (m_mainLoop) {
@@ -201,6 +222,11 @@ private:
             m_mainLoop = 0;
         }
 
+        if (m_context) {
+            pa_context_unref(m_context);
+            m_context = 0;
+        }
+
         m_prepared = false;
     }
 
@@ -227,6 +253,8 @@ private:
     pa_context *m_context;
     pa_threaded_mainloop *m_mainLoop;
     pa_mainloop_api *m_mainLoopApi;
+    uint m_lockCount;
+    QAtomicInt m_ref;
 };
 
 }
@@ -331,6 +359,8 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
     m_position(0),
     m_resourcesAvailable(false)
 {
+    pulseDaemon()->ref();
+
     m_ref = new QSoundEffectRef(this);
     pa_sample_spec_init(&m_pulseSpec);
 
@@ -374,6 +404,9 @@ void QSoundEffectPrivate::setCategory(const QString &category)
 {
     if (m_category != category) {
         m_category = category;
+
+        PulseDaemonLocker locker;
+
         if (m_playing || m_playQueued) {
             // Currently playing, we need to disconnect when
             // playback stops
@@ -396,6 +429,8 @@ QSoundEffectPrivate::~QSoundEffectPrivate()
     QMediaResourcePolicy::destroyResourceSet(m_resources);
     m_resources = 0;
     m_ref->release();
+
+    pulseDaemon()->deref();
 }
 
 QStringList QSoundEffectPrivate::supportedMimeTypes()
@@ -417,6 +452,8 @@ void QSoundEffectPrivate::setSource(const QUrl &url)
     qDebug() << this << "setSource =" << url;
 #endif
 
+    PulseDaemonLocker locker;
+
     // Make sure the stream is empty before loading a new source (otherwise whatever is there will
     // be played before the new source)
     emptyStream();
@@ -435,7 +472,6 @@ void QSoundEffectPrivate::setSource(const QUrl &url)
     m_source = url;
     m_sampleReady = false;
 
-    PulseDaemonLocker locker;
     setLoopsRemaining(0);
     if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) {
         pa_stream_set_write_callback(m_pulseStream, 0, 0);
@@ -484,8 +520,10 @@ void QSoundEffectPrivate::setLoopCount(int loopCount)
     if (loopCount == 0)
         loopCount = 1;
     m_loopCount = loopCount;
-    if (m_playing)
+    if (m_playing) {
+        PulseDaemonLocker locker;
         setLoopsRemaining(loopCount);
+    }
 }
 
 qreal QSoundEffectPrivate::volume() const
@@ -588,6 +626,7 @@ void QSoundEffectPrivate::playAvailable()
         return;
 
     PulseDaemonLocker locker;
+
     if (!m_pulseStream || m_status != QSoundEffect::Ready || m_stopping || m_emptying) {
 #ifdef QT_PA_DEBUG
         qDebug() << this << "play deferred";
@@ -623,6 +662,8 @@ void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options)
     pa_stream_success_cb_t flushCompleteCb = reloadSample ? stream_flush_reload_callback
                                                           : stream_flush_callback;
 
+    PulseDaemonLocker locker;
+
     m_emptying = true;
     pa_stream_set_write_callback(m_pulseStream, 0, 0);
     pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
@@ -635,11 +676,12 @@ void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options)
 
 void QSoundEffectPrivate::emptyComplete(void *stream, bool reload)
 {
-    PulseDaemonLocker locker;
 #ifdef QT_PA_DEBUG
     qDebug() << this << "emptyComplete";
 #endif
 
+    PulseDaemonLocker locker;
+
     m_emptying = false;
 
     if ((pa_stream *)stream == m_pulseStream) {
@@ -653,6 +695,14 @@ void QSoundEffectPrivate::emptyComplete(void *stream, bool reload)
 
 void QSoundEffectPrivate::sampleReady()
 {
+    PulseDaemonLocker locker;
+
+    // The slot might be called right after a new call to setSource().
+    // In this case, the sample has been reset and the slot is being called for the previous sample.
+    // Just ignore it.
+    if (Q_UNLIKELY(!m_sample || m_sample->state() != QSample::Ready))
+        return;
+
 #ifdef QT_PA_DEBUG
     qDebug() << this << "sampleReady";
 #endif
@@ -671,8 +721,7 @@ void QSoundEffectPrivate::sampleReady()
     if (m_name.isNull())
         m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
 
-    PulseDaemonLocker locker;
-    if (m_pulseStream) {
+    if (m_pulseStream && pa_stream_get_state(m_pulseStream) == PA_STREAM_READY) {
 #ifdef QT_PA_DEBUG
         qDebug() << this << "reuse existing pulsestream";
 #endif
@@ -689,7 +738,7 @@ void QSoundEffectPrivate::sampleReady()
         } else {
             streamReady();
         }
-    } else {
+    } else if (!m_pulseStream) {
         if (!pulseDaemon()->context() || pa_context_get_state(pulseDaemon()->context()) != PA_CONTEXT_READY) {
             connect(pulseDaemon(), SIGNAL(contextReady()), SLOT(contextReady()));
             return;
@@ -760,12 +809,21 @@ void QSoundEffectPrivate::prepare()
 
 void QSoundEffectPrivate::uploadSample()
 {
+    // Always called on PulseAudio thread
+
     if (m_runningCount == 0) {
 #ifdef QT_PA_DEBUG
     qDebug() << this << "uploadSample: return due to 0 m_runningCount";
 #endif
         return;
     }
+
+    if (Q_UNLIKELY(!m_pulseStream
+                   || pa_stream_get_state(m_pulseStream) != PA_STREAM_READY
+                   || !m_sampleReady)) {
+        return;
+    }
+
 #ifdef QT_PA_DEBUG
     qDebug() << this << "uploadSample: m_runningCount =" << m_runningCount;
 #endif
@@ -814,6 +872,11 @@ void QSoundEffectPrivate::uploadSample()
 
 int QSoundEffectPrivate::writeToStream(const void *data, int size)
 {
+    // Always called on PulseAudio thread
+
+    if (size < 1)
+        return 0;
+
     m_volumeLock.lockForRead();
     qreal volume = m_muted ? 0 : m_volume;
     m_volumeLock.unlock();
@@ -847,6 +910,8 @@ int QSoundEffectPrivate::writeToStream(const void *data, int size)
 
 void QSoundEffectPrivate::playSample()
 {
+    PulseDaemonLocker locker;
+
 #ifdef QT_PA_DEBUG
     qDebug() << this << "playSample";
 #endif
@@ -864,8 +929,11 @@ void QSoundEffectPrivate::stop()
 #endif
     if (!m_playing)
         return;
-    setPlaying(false);
+
     PulseDaemonLocker locker;
+
+    setPlaying(false);
+
     m_stopping = true;
     if (m_pulseStream) {
         emptyStream(ReloadSampleWhenDone);
@@ -886,10 +954,17 @@ void QSoundEffectPrivate::underRun()
 
 void QSoundEffectPrivate::streamReady()
 {
+    PulseDaemonLocker locker;
+
+    if (Q_UNLIKELY(!m_sample || m_sample->state() != QSample::Ready
+                   || !m_pulseStream || pa_stream_get_state(m_pulseStream) != PA_STREAM_READY)) {
+        return;
+    }
+
 #ifdef QT_PA_DEBUG
     qDebug() << this << "streamReady";
 #endif
-    PulseDaemonLocker locker;
+
     m_sinkInputId =  pa_stream_get_index(m_pulseStream);
 #ifdef QT_PA_DEBUG
     const pa_buffer_attr *realBufAttr = pa_stream_get_buffer_attr(m_pulseStream);
@@ -973,6 +1048,9 @@ void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata)
 #ifdef QT_PA_DEBUG
             qDebug() << self << "pulse stream ready";
 #endif
+            if (Q_UNLIKELY(!self->m_sample || self->m_sample->state() != QSample::Ready))
+                return;
+
             const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(self->m_pulseStream);
             self->m_pulseBufferSize = bufferAttr->tlength;
             if (bufferAttr->prebuf > uint32_t(self->m_sample->data().size())) {
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp
index 3d5e5c8300d2ef0993cc80a1d8086250315c14e8..60a968813cc33d98041f9d70c110e60191756702 100644
--- a/src/multimediawidgets/qvideowidget.cpp
+++ b/src/multimediawidgets/qvideowidget.cpp
@@ -55,6 +55,9 @@
 #include <qboxlayout.h>
 #include <qnamespace.h>
 
+#include <qwindow.h>
+#include <private/qhighdpiscaling_p.h>
+
 using namespace Qt;
 
 QT_BEGIN_NAMESPACE
@@ -372,11 +375,23 @@ QSize QWindowVideoWidgetBackend::sizeHint() const
     return m_windowControl->nativeSize();
 }
 
+void QWindowVideoWidgetBackend::updateDisplayRect()
+{
+    QRect rect = m_widget->rect();
+    if (QHighDpiScaling::isActive()) {
+        const qreal factor = QHighDpiScaling::factor(m_widget->windowHandle());
+        if (!qFuzzyCompare(factor, qreal(1))) {
+            rect = QRectF(QPointF(rect.topLeft()) * factor,
+                          QSizeF(rect.size()) * factor).toRect();
+        }
+    }
+    m_windowControl->setDisplayRect(rect);
+}
+
 void QWindowVideoWidgetBackend::showEvent()
 {
     m_windowControl->setWinId(m_widget->winId());
-
-    m_windowControl->setDisplayRect(m_widget->rect());
+    updateDisplayRect();
 
 #if defined(Q_WS_WIN)
     m_widget->setUpdatesEnabled(false);
@@ -392,12 +407,12 @@ void QWindowVideoWidgetBackend::hideEvent(QHideEvent *)
 
 void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *)
 {
-    m_windowControl->setDisplayRect(m_widget->rect());
+    updateDisplayRect();
 }
 
 void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *)
 {
-    m_windowControl->setDisplayRect(m_widget->rect());
+    updateDisplayRect();
 }
 
 void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event)
diff --git a/src/multimediawidgets/qvideowidget_p.h b/src/multimediawidgets/qvideowidget_p.h
index 6ef4c364566c157cc7b909a4b7f5829270971db1..48b08e09338e0690a8bfc8751c83165941d01836 100644
--- a/src/multimediawidgets/qvideowidget_p.h
+++ b/src/multimediawidgets/qvideowidget_p.h
@@ -211,6 +211,8 @@ public:
 #endif
 
 private:
+    void updateDisplayRect();
+
     QMediaService *m_service;
     QVideoWindowControl *m_windowControl;
     QWidget *m_widget;
diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp
index 9718c78b50d165ed4e67069f8715d6d86c4829ff..ae3d69fc23a513bd0ff71ec29a05d3a549ed9984 100644
--- a/src/plugins/common/evr/evrd3dpresentengine.cpp
+++ b/src/plugins/common/evr/evrd3dpresentengine.cpp
@@ -255,7 +255,7 @@ QVariant IMFSampleVideoBuffer::handle() const
     if (handleType() != GLTextureHandle)
         return handle;
 
-    if (m_textureUpdated || m_engine->updateTexture(m_surface)) {
+    if (m_engine->m_glResources && (m_textureUpdated || m_engine->updateTexture(m_surface))) {
         m_textureUpdated = true;
         handle = QVariant::fromValue<unsigned int>(m_engine->m_glResources->glTexture);
     }
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
index 01103d6594cde8ad06fa7c8df33dbb852a6b3971..b9e29245fbb890207e2c07647488777fd2dc772a 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
@@ -93,7 +93,8 @@ static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys()
 
         //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlSmall);
         //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlLarge);
-        metadataKeys->insert(GST_TAG_PREVIEW_IMAGE, QMediaMetaData::CoverArtImage);
+        metadataKeys->insert(GST_TAG_PREVIEW_IMAGE, QMediaMetaData::ThumbnailImage);
+        metadataKeys->insert(GST_TAG_IMAGE, QMediaMetaData::CoverArtImage);
 
         // Image/Video
         metadataKeys->insert("resolution", QMediaMetaData::Resolution);
diff --git a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp
index 561d9e03c8391a87a76d9f999594c739c543714b..b3fd11111a0bbcb042fb9e459ca695ee5d798ec9 100644
--- a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp
+++ b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp
@@ -356,6 +356,13 @@ void QWinRTAbstractVideoRendererControl::setActive(bool active)
         if (!d->surface)
             return;
 
+        // This only happens for quick restart scenarios, for instance
+        // when switching cameras.
+        if (d->renderThread.isRunning() && d->renderThread.isInterruptionRequested()) {
+            CriticalSectionLocker lock(&d->mutex);
+            d->renderThread.wait();
+        }
+
         if (!d->surface->isActive())
             d->surface->start(d->format);
 
@@ -363,7 +370,8 @@ void QWinRTAbstractVideoRendererControl::setActive(bool active)
         return;
     }
 
-    shutdown();
+    d->renderThread.requestInterruption();
+
     if (d->surface && d->surface->isActive())
         d->surface->stop();
 }
diff --git a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp b/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
index 5720488f205f6eaae71d439399067396665acbc4..a4df6306f4fdc4458e224ddc6a0db44e81ebbc5c 100644
--- a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
+++ b/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
@@ -267,7 +267,8 @@ public:
         }
 
         if (d->videoRenderer)
-            d->videoRenderer->setActive(d->state == QMediaPlayer::PlayingState);
+            d->videoRenderer->setActive(d->state == QMediaPlayer::PlayingState &&
+                                        d->videoRenderer->size().isValid());
 
         const QMediaPlayer::MediaStatus oldMediaStatus = d->mediaStatus;
         const QMediaPlayer::State oldState = d->state;
diff --git a/tests/auto/integration/qsoundeffect/BLACKLIST b/tests/auto/integration/qsoundeffect/BLACKLIST
deleted file mode 100644
index 467169fcfccbe130b80e7f6383249fefb2b7afd8..0000000000000000000000000000000000000000
--- a/tests/auto/integration/qsoundeffect/BLACKLIST
+++ /dev/null
@@ -1,9 +0,0 @@
-[testSetSourceWhileLoading]
-linux
-
-#QTBUG-55735
-[testSetSourceWhilePlaying]
-linux
-
-[testSetSourceWhileLoading]
-linux