diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
index c9f12aeb6b7057c8081a824fa595adbfe9960939..38052de3242e0ca0f7797afb66fe53e71b096a04 100644
--- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
@@ -45,9 +45,6 @@
 #include "qsoundeffect_qaudio_p.h"
 
 #include <QtCore/qcoreapplication.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
 #include <QtCore/qiodevice.h>
 
 //#include <QDebug>
diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/playlistfileparser.cpp
index ac556c25c90abb39db29d5d9cef5d7c861ace7c0..a3aba1cab867ce2e30bbba850e07d6030fde19ad 100644
--- a/src/multimedia/playback/playlistfileparser.cpp
+++ b/src/multimedia/playback/playlistfileparser.cpp
@@ -51,6 +51,30 @@ public:
 
     virtual void parseLine(int lineIndex, const QString& line, const QUrl& root) = 0;
 
+protected:
+    QUrl expandToFullPath(const QUrl &root, const QString &line)
+    {
+        // On Linux, backslashes are not converted to forward slashes :/
+        if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
+            // Network share paths are not resolved
+            return QUrl::fromLocalFile(line);
+        }
+
+        QUrl url(line);
+        if (url.scheme().isEmpty()) {
+            // Resolve it relative to root
+            if (root.isLocalFile())
+                return root.resolved(QUrl::fromLocalFile(line));
+            else
+                return root.resolved(url);
+        } else if (url.scheme().length() == 1) {
+            // Assume it's a drive letter for a Windows path
+            url = QUrl::fromLocalFile(line);
+        }
+
+        return url;
+    }
+
 Q_SIGNALS:
     void newItem(const QVariant& content);
     void finished();
@@ -138,29 +162,6 @@ public:
         return -1;
     }
 
-    QUrl expandToFullPath(const QUrl& root, const QString& line)
-    {
-        // On Linux, backslashes are not converted to forward slashes :/
-        if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
-            // Network share paths are not resolved
-            return QUrl::fromLocalFile(line);
-        }
-
-        QUrl url(line);
-        if (url.scheme().isEmpty()) {
-            // Resolve it relative to root
-            if (root.isLocalFile())
-                return root.resolved(QUrl::fromLocalFile(line));
-            else
-                return root.resolved(url);
-        } else if (url.scheme().length() == 1) {
-            // Assume it's a drive letter for a Windows path
-            url = QUrl::fromLocalFile(line);
-        }
-
-        return url;
-    }
-
 private:
     bool            m_extendedFormat;
     QVariantMap     m_extraInfo;
@@ -172,27 +173,9 @@ class PLSParser : public ParserBase
 public:
     PLSParser(QObject *parent)
         : ParserBase(parent)
-        , m_state(Header)
-        , m_count(0)
-        , m_readFlags(0)
     {
     }
 
-    enum ReadFlags
-    {
-        FileRead = 0x1,
-        TitleRead = 0x2,
-        LengthRead = 0x4,
-        All = FileRead | TitleRead | LengthRead
-    };
-
-    enum State
-    {
-        Header,
-        Track,
-        Footer
-    };
-
 /*
  *
 The format is essentially that of an INI file structured as follows:
@@ -231,89 +214,25 @@ NumberOfEntries=2
 
 Version=2
 */
-    inline bool containsFlag(const ReadFlags& flag)
+    void parseLine(int, const QString &line, const QUrl &root)
     {
-        return (m_readFlags & int(flag)) == flag;
-    }
+        // We ignore everything but 'File' entries, since that's the only thing we care about.
+        if (!line.startsWith(QLatin1String("File")))
+            return;
 
-    inline void setFlag(const ReadFlags& flag)
-    {
-        m_readFlags |= int(flag);
-    }
+        QString value = getValue(line);
+        if (value.isEmpty())
+            return;
 
-    void parseLine(int lineIndex, const QString& line, const QUrl&)
-    {
-        switch (m_state) {
-        case Header:
-            if (line == QLatin1String("[playlist]")) {
-                m_state = Track;
-                setCount(1);
-            }
-            break;
-        case Track:
-            if (!containsFlag(FileRead) && line.startsWith(m_fileName)) {
-                m_item[QLatin1String("url")] = getValue(lineIndex, line);
-                setFlag(FileRead);
-            } else if (!containsFlag(TitleRead) && line.startsWith(m_titleName)) {
-                m_item[QMediaMetaData::Title] = getValue(lineIndex, line);
-                setFlag(TitleRead);
-            } else if (!containsFlag(LengthRead) && line.startsWith(m_lengthName)) {
-                //convert from seconds to miliseconds
-                int length = getValue(lineIndex, line).toInt();
-                if (length > 0)
-                    m_item[QMediaMetaData::Duration] = length * 1000;
-                setFlag(LengthRead);
-            } else if (line.startsWith(QLatin1String("NumberOfEntries"))) {
-                m_state = Footer;
-                int entries = getValue(lineIndex, line).toInt();
-                int count = m_readFlags == 0 ? (m_count - 1) : m_count;
-                if (entries != count) {
-                    emit error(QPlaylistFileParser::FormatError, tr("Error parsing playlist: %1, expected count = %2").
-                               arg(line, QString::number(count)));
-                }
-                break;
-            }
-            if (m_readFlags == int(All)) {
-                emit newItem(m_item);
-                setCount(m_count + 1);
-            }
-            break;
-        case Footer:
-            if (line.startsWith(QLatin1String("Version"))) {
-                int version = getValue(lineIndex, line).toInt();
-                if (version != 2)
-                    emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1], expected version = 2")).arg(line));
-            }
-            break;
-        }
+        emit newItem(expandToFullPath(root, value));
     }
 
-    QString getValue(int lineIndex, const QString& line) {
+    QString getValue(const QString& line) {
         int start = line.indexOf('=');
-        if (start < 0) {
-            emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1]:%2")).arg(QString::number(lineIndex), line));
+        if (start < 0)
             return QString();
-        }
         return line.midRef(start + 1).trimmed().toString();
     }
-
-    void setCount(int count) {
-        m_count = count;
-        m_fileName = QStringLiteral("File%1").arg(count);
-        m_titleName = QStringLiteral("Title%1").arg(count);
-        m_lengthName = QStringLiteral("Length%1").arg(count);
-        m_item.clear();
-        m_readFlags = 0;
-    }
-
-private:
-    State m_state;
-    int  m_count;
-    QString m_titleName;
-    QString m_fileName;
-    QString m_lengthName;
-    QVariantMap m_item;
-    int m_readFlags;
 };
 }
 
diff --git a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp
index baf6474e5495f0cbbe1a5d550f2561fd19ff1c8b..2b89ef17d2e84dd29c7369e6040bd601b3d95268 100644
--- a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp
+++ b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp
@@ -82,6 +82,8 @@ void QMediaNetworkPlaylistProviderPrivate::_q_handleParserError(QPlaylistFilePar
         break;
     }
 
+    parser.stop();
+
     emit q->loadFailed(playlistError, errorMessage);
 }
 
diff --git a/src/plugins/alsa/qalsaaudioinput.cpp b/src/plugins/alsa/qalsaaudioinput.cpp
index bb0182a3e7ddde56fe6569bf36196e42ac9618b3..adaa41c6ee797ef47e2015e7326aa29d1c1d2027 100644
--- a/src/plugins/alsa/qalsaaudioinput.cpp
+++ b/src/plugins/alsa/qalsaaudioinput.cpp
@@ -760,7 +760,7 @@ qint64 QAlsaAudioInput::elapsedUSecs() const
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-    return clockStamp.elapsed()*1000;
+    return clockStamp.elapsed() * qint64(1000);
 }
 
 void QAlsaAudioInput::reset()
diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp
index 07dd17362c982c5920c697247227370ed6ca3851..fde2bc9bfdedd659b9a9108152b050c699482a7f 100644
--- a/src/plugins/alsa/qalsaaudiooutput.cpp
+++ b/src/plugins/alsa/qalsaaudiooutput.cpp
@@ -774,7 +774,7 @@ qint64 QAlsaAudioOutput::elapsedUSecs() const
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-    return clockStamp.elapsed()*1000;
+    return clockStamp.elapsed() * qint64(1000);
 }
 
 void QAlsaAudioOutput::reset()
diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp
index 9e344b4639ed75d6dc76e3afa76f2ed6dc58aac0..cd592a7d6838eea4f862aed6d7493486a6301543 100644
--- a/src/plugins/opensles/qopenslesaudioinput.cpp
+++ b/src/plugins/opensles/qopenslesaudioinput.cpp
@@ -474,7 +474,7 @@ qint64 QOpenSLESAudioInput::elapsedUSecs() const
     if (m_deviceState == QAudio::StoppedState)
         return 0;
 
-    return m_clockStamp.elapsed() * 1000;
+    return m_clockStamp.elapsed() * qint64(1000);
 }
 
 void QOpenSLESAudioInput::setVolume(qreal vol)
diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp
index 06f2261df2afeb1983feae4612ec4d51d3437267..c45fbd3c5eb3a12531deb835bfbf1c88a1ad327b 100644
--- a/src/plugins/opensles/qopenslesaudiooutput.cpp
+++ b/src/plugins/opensles/qopenslesaudiooutput.cpp
@@ -273,7 +273,7 @@ qint64 QOpenSLESAudioOutput::elapsedUSecs() const
     if (m_state == QAudio::StoppedState)
         return 0;
 
-    return m_clockStamp.elapsed() * 1000;
+    return m_clockStamp.elapsed() * qint64(1000);
 }
 
 void QOpenSLESAudioOutput::reset()
diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
index b97cd6c4fda78c9899ee82d8264a1a5427923d3d..ea053578f2f31a4a314195e5c8cef30a10246b70 100644
--- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
@@ -684,7 +684,7 @@ qint64 QPulseAudioInput::elapsedUSecs() const
     if (m_deviceState == QAudio::StoppedState)
         return 0;
 
-    return m_clockStamp.elapsed() * 1000;
+    return m_clockStamp.elapsed() * qint64(1000);
 }
 
 void QPulseAudioInput::reset()
diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
index c55cfe44cc88883fa8907ae19f20c351bd4147c0..b979450b6f4f5fe2205c0d4d343d6b1e79de74ca 100644
--- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
@@ -596,7 +596,7 @@ qint64 QPulseAudioOutput::elapsedUSecs() const
     if (m_deviceState == QAudio::StoppedState)
         return 0;
 
-    return m_clockStamp.elapsed() * 1000;
+    return m_clockStamp.elapsed() * qint64(1000);
 }
 
 void QPulseAudioOutput::reset()
diff --git a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
index ea9ea5abffd3c03ac52c122e1d8644257b197740..3f60dfc29baf47ef2f3b1c23e4248fcf060a1c11 100644
--- a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
@@ -186,7 +186,7 @@ qint64 QnxAudioInput::elapsedUSecs() const
     if (m_state == QAudio::StoppedState)
         return 0;
 
-    return m_clockStamp.elapsed() * 1000;
+    return m_clockStamp.elapsed() * qint64(1000);
 }
 
 QAudio::Error QnxAudioInput::error() const
diff --git a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
index 4604ed54236151d41284b6b016ba5577c534d8b4..e7733276e3144bce1bc8fb22b527b6d043c3f1e0 100644
--- a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
@@ -172,7 +172,7 @@ qint64 QnxAudioOutput::elapsedUSecs() const
     if (m_state == QAudio::StoppedState)
         return 0;
     else
-        return m_startTimeStamp.elapsed() * 1000;
+        return m_startTimeStamp.elapsed() * qint64(1000);
 }
 
 QAudio::Error QnxAudioOutput::error() const
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
index 217f8b3bbe2ec14f282f64e1fde9f61483dac58a..503c5beb87bcb97087d18abd227e9e8361972601 100644
--- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
@@ -538,6 +538,7 @@ void MmRendererMediaPlayerControl::play()
         return;
     }
 
+    m_stopEventsToIgnore = 0;    // once playing, stop events must be proccessed
     setState( QMediaPlayer::PlayingState);
 }
 
diff --git a/src/plugins/windowsaudio/qwindowsaudioinput.cpp b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
index 376854373d239664f89f7d4aacf1809a6f7b887e..2a3d34293eefe028c8a32987732ba1fd1cc98fdf 100644
--- a/src/plugins/windowsaudio/qwindowsaudioinput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
@@ -698,7 +698,7 @@ qint64 QWindowsAudioInput::elapsedUSecs() const
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-    return timeStampOpened.elapsed()*1000;
+    return timeStampOpened.elapsed() * qint64(1000);
 }
 
 void QWindowsAudioInput::reset()
diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
index 659ee3a0c344b5d7fa169e314823959b1d5f920e..a9230139c4f4daf958b19e541ae3cb63b4b02ef6 100644
--- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
@@ -674,7 +674,7 @@ qint64 QWindowsAudioOutput::elapsedUSecs() const
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-    return timeStampOpened.elapsed()*1000;
+    return timeStampOpened.elapsed() * qint64(1000);
 }
 
 QAudio::Error QWindowsAudioOutput::error() const
diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
index 93c1841bcfbb910f8ac68a29628ec8287089aac0..da69f926f606da087e51c5e7b47be682fb4012fc 100644
--- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
+++ b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
@@ -236,7 +236,6 @@ void MFAudioDecoderControl::handleMediaSourceReady()
     }
 
     if (m_sourceResolver->mediaSource()) {
-        IMFPresentationDescriptor *pd = 0;
         if (mediaType && m_resampler) {
             HRESULT hr = S_OK;
             hr = m_resampler->SetInputType(m_mfInputStreamID, mediaType, 0);
@@ -246,9 +245,11 @@ void MFAudioDecoderControl::handleMediaSourceReady()
                 qWarning() << "MFAudioDecoderControl: failed to SetInputType of resampler" << hr;
             }
         }
+        IMFPresentationDescriptor *pd;
         if (SUCCEEDED(m_sourceResolver->mediaSource()->CreatePresentationDescriptor(&pd))) {
             UINT64 duration = 0;
             pd->GetUINT64(MF_PD_DURATION, &duration);
+            pd->Release();
             duration /= 10000;
             if (m_duration != qint64(duration)) {
                 m_duration = qint64(duration);
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 4ddb82ee611e60beb6c950710ed6c9d0163f19bc..08baa779ab70106e413e651135a5e082f9b3da7b 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -258,6 +258,7 @@ void MFPlayerSession::handleMediaSourceReady()
         //convert from 100 nanosecond to milisecond
         emit durationUpdate(qint64(m_duration / 10000));
         setupPlaybackTopology(mediaSource, sourcePD);
+        sourcePD->Release();
     } else {
         changeStatus(QMediaPlayer::InvalidMedia);
         emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
@@ -415,12 +416,15 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
                 if (SUCCEEDED(hr)) {
                     hr = node->SetUINT32(MF_TOPONODE_STREAMID, sinkID);
                     if (SUCCEEDED(hr)) {
-                        if (SUCCEEDED(topology->AddNode(node)))
+                        if (SUCCEEDED(topology->AddNode(node))) {
+                            handler->Release();
                             return node;
+                        }
                     }
                 }
             }
         }
+        handler->Release();
     }
     node->Release();
     return NULL;
@@ -609,42 +613,39 @@ HRESULT BindOutputNode(IMFTopologyNode *pNode)
 // Sets the IMFStreamSink pointers on all of the output nodes in a topology.
 HRESULT BindOutputNodes(IMFTopology *pTopology)
 {
-    DWORD cNodes = 0;
-
-    IMFCollection *collection = NULL;
-    IUnknown *element = NULL;
-    IMFTopologyNode *node = NULL;
+    IMFCollection *collection;
 
     // Get the collection of output nodes.
     HRESULT hr = pTopology->GetOutputNodeCollection(&collection);
 
     // Enumerate all of the nodes in the collection.
-    if (SUCCEEDED(hr))
+    if (SUCCEEDED(hr)) {
+        DWORD cNodes;
         hr = collection->GetElementCount(&cNodes);
 
-    if (SUCCEEDED(hr)) {
-        for (DWORD i = 0; i < cNodes; i++) {
-            hr = collection->GetElement(i, &element);
-            if (FAILED(hr))
-                break;
+        if (SUCCEEDED(hr)) {
+            for (DWORD i = 0; i < cNodes; i++) {
+                IUnknown *element;
+                hr = collection->GetElement(i, &element);
+                if (FAILED(hr))
+                    break;
 
-            hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
-            if (FAILED(hr))
-                break;
+                IMFTopologyNode *node;
+                hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
+                element->Release();
+                if (FAILED(hr))
+                    break;
 
-            // Bind this node.
-            hr = BindOutputNode(node);
-            if (FAILED(hr))
-                break;
+                // Bind this node.
+                hr = BindOutputNode(node);
+                node->Release();
+                if (FAILED(hr))
+                    break;
+            }
         }
+        collection->Release();
     }
 
-    if (collection)
-        collection->Release();
-    if (element)
-        element->Release();
-    if (node)
-        node->Release();
     return hr;
 }
 
@@ -1502,8 +1503,11 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
         }
     }
 
-    if (!m_closing)
+    if (!m_closing) {
         emit sessionEvent(pEvent);
+    } else {
+        pEvent->Release();
+    }
     return S_OK;
 }
 
@@ -1626,9 +1630,6 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
                 }
             }
 
-            if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
-                setVolumeInternal(m_muted ? 0 : m_volume);
-
             DWORD dwCharacteristics = 0;
             m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
             emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
@@ -1699,6 +1700,9 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
                         }
                     }
                     MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));
+
+                    if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
+                        setVolumeInternal(m_muted ? 0 : m_volume);
                 }
             }
         }
diff --git a/src/plugins/wmf/samplegrabber.cpp b/src/plugins/wmf/samplegrabber.cpp
index 016482e5d7c9b8b57637654e8dfb54b67f8ab0ca..0a11d8bb82a26817d7b37730997ebbdb9f67a957 100644
--- a/src/plugins/wmf/samplegrabber.cpp
+++ b/src/plugins/wmf/samplegrabber.cpp
@@ -155,6 +155,9 @@ STDMETHODIMP AudioSampleGrabberCallback::OnProcessSample(REFGUID guidMajorMediaT
     if (llSampleTime == _I64_MAX) {
         // Set default QAudioBuffer start time
         llSampleTime = -1;
+    } else {
+        // WMF uses 100-nanosecond units, Qt uses microseconds
+        llSampleTime /= 10;
     }
 
     foreach (MFAudioProbeControl* probe, m_audioProbes)
diff --git a/tests/auto/unit/qmediaplaylist/testdata/empty.pls b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
new file mode 100644
index 0000000000000000000000000000000000000000..639c22b0c2b9eeb7839697b5f867200132163149
--- /dev/null
+++ b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
@@ -0,0 +1,2 @@
+[playlist]
+NumberOfEntries=100
diff --git a/tests/auto/unit/qmediaplaylist/testdata/test.pls b/tests/auto/unit/qmediaplaylist/testdata/test.pls
new file mode 100644
index 0000000000000000000000000000000000000000..18832b1019ca10511ff631f39a88d47cc8a4dce8
--- /dev/null
+++ b/tests/auto/unit/qmediaplaylist/testdata/test.pls
@@ -0,0 +1,27 @@
+[playlist]
+
+File1=http://test.host/path
+Title1=First
+Length1=-1
+File2= http://test.host/path
+Title2=Second
+Length2=-1
+File3=testfile
+Title3=Third
+Length3=-1
+
+
+
+File4=testdir/testfile
+Title4=Fourth
+Length4=-1
+File5=/testdir/testfile
+Title5=Fifth
+Length5=-1
+File6=file://path/name#suffix
+Title6=Sixth
+Length6=-1
+File7=testfile2#suffix
+Title7=Seventh
+Length7=-1
+NumberOfEntries=7
diff --git a/tests/auto/unit/qmediaplaylist/testdata/totem-pl-example.pls b/tests/auto/unit/qmediaplaylist/testdata/totem-pl-example.pls
new file mode 100644
index 0000000000000000000000000000000000000000..385fe2a30eff8ac061a57e9c97ee97788c79a74c
--- /dev/null
+++ b/tests/auto/unit/qmediaplaylist/testdata/totem-pl-example.pls
@@ -0,0 +1,5 @@
+[playlist]
+X-GNOME-Title=totem-pl-file-example
+NumberOfEntries=1
+File1=http://test.host/path
+Title1=Silence
diff --git a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
index 08d63c858fbb95e639d87d0562e25a788d617838..b867604e8662b7a381f90b8bc0f8be4eb9c36775 100644
--- a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
+++ b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
@@ -78,6 +78,7 @@ private slots:
     void currentItem();
     void saveAndLoad();
     void loadM3uFile();
+    void loadPLSFile();
     void playbackMode();
     void playbackMode_data();
     void shuffle();
@@ -348,8 +349,10 @@ void tst_QMediaPlaylist::saveAndLoad()
     QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
     QVERIFY(!playlist.errorString().isEmpty());
 
+    QSignalSpy loadedSignal(&playlist, SIGNAL(loaded()));
     QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed()));
     playlist.load(&buffer, "unsupported_format");
+    QTRY_VERIFY(loadedSignal.isEmpty());
     QCOMPARE(errorSignal.size(), 1);
     QVERIFY(playlist.error() != QMediaPlaylist::NoError);
     QVERIFY(!playlist.errorString().isEmpty());
@@ -359,8 +362,10 @@ void tst_QMediaPlaylist::saveAndLoad()
     QVERIFY(playlist.error() != QMediaPlaylist::NoError);
     QVERIFY(!playlist.errorString().isEmpty());
 
+    loadedSignal.clear();
     errorSignal.clear();
     playlist.load(QUrl::fromLocalFile(QLatin1String("tmp.unsupported_format")), "unsupported_format");
+    QTRY_VERIFY(loadedSignal.isEmpty());
     QCOMPARE(errorSignal.size(), 1);
     QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError);
     QVERIFY(!playlist.errorString().isEmpty());
@@ -372,7 +377,11 @@ void tst_QMediaPlaylist::saveAndLoad()
     buffer.seek(0);
 
     QMediaPlaylist playlist2;
+    QSignalSpy loadedSignal2(&playlist2, SIGNAL(loaded()));
+    QSignalSpy errorSignal2(&playlist2, SIGNAL(loadFailed()));
     playlist2.load(&buffer, "m3u");
+    QCOMPARE(loadedSignal2.size(), 1);
+    QTRY_VERIFY(errorSignal2.isEmpty());
     QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
 
     QCOMPARE(playlist.mediaCount(), playlist2.mediaCount());
@@ -382,9 +391,13 @@ void tst_QMediaPlaylist::saveAndLoad()
     res = playlist.save(QUrl::fromLocalFile(QLatin1String("tmp.m3u")), "m3u");
     QVERIFY(res);
 
+    loadedSignal2.clear();
+    errorSignal2.clear();
     playlist2.clear();
     QVERIFY(playlist2.isEmpty());
     playlist2.load(QUrl::fromLocalFile(QLatin1String("tmp.m3u")), "m3u");
+    QCOMPARE(loadedSignal2.size(), 1);
+    QTRY_VERIFY(errorSignal2.isEmpty());
     QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
 
     QCOMPARE(playlist.mediaCount(), playlist2.mediaCount());
@@ -398,12 +411,20 @@ void tst_QMediaPlaylist::loadM3uFile()
     QMediaPlaylist playlist;
 
     // Try to load playlist that does not exist in the testdata folder
+    QSignalSpy loadSpy(&playlist, SIGNAL(loaded()));
+    QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed()));
     QString testFileName = QFINDTESTDATA("testdata");
     playlist.load(QUrl::fromLocalFile(testFileName + "/missing_file.m3u"));
+    QTRY_VERIFY(loadSpy.isEmpty());
+    QVERIFY(!loadFailedSpy.isEmpty());
     QVERIFY(playlist.error() != QMediaPlaylist::NoError);
 
+    loadSpy.clear();
+    loadFailedSpy.clear();
     testFileName = QFINDTESTDATA("testdata/test.m3u");
     playlist.load(QUrl::fromLocalFile(testFileName));
+    QTRY_VERIFY(!loadSpy.isEmpty());
+    QVERIFY(loadFailedSpy.isEmpty());
     QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
     QCOMPARE(playlist.mediaCount(), 7);
 
@@ -420,10 +441,80 @@ void tst_QMediaPlaylist::loadM3uFile()
     //ensure #2 suffix is not stripped from path
     testFileName = QFINDTESTDATA("testdata/testfile2#suffix");
     QCOMPARE(playlist.media(6).canonicalUrl(), QUrl::fromLocalFile(testFileName));
+
     // check ability to load from QNetworkRequest
+    loadSpy.clear();
+    loadFailedSpy.clear();
+    playlist.load(QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.m3u"))));
+    QTRY_VERIFY(!loadSpy.isEmpty());
+    QVERIFY(loadFailedSpy.isEmpty());
+}
+
+void tst_QMediaPlaylist::loadPLSFile()
+{
+    QMediaPlaylist playlist;
+
+    // Try to load playlist that does not exist in the testdata folder
     QSignalSpy loadSpy(&playlist, SIGNAL(loaded()));
     QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed()));
-    playlist.load(QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.m3u"))));
+    QString testFileName = QFINDTESTDATA("testdata");
+    playlist.load(QUrl::fromLocalFile(testFileName + "/missing_file.pls"));
+    QTRY_VERIFY(loadSpy.isEmpty());
+    QVERIFY(!loadFailedSpy.isEmpty());
+    QVERIFY(playlist.error() != QMediaPlaylist::NoError);
+
+    // Try to load empty playlist
+    loadSpy.clear();
+    loadFailedSpy.clear();
+    testFileName = QFINDTESTDATA("testdata/empty.pls");
+    playlist.load(QUrl::fromLocalFile(testFileName));
+    QTRY_VERIFY(!loadSpy.isEmpty());
+    QVERIFY(loadFailedSpy.isEmpty());
+    QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+    QCOMPARE(playlist.mediaCount(), 0);
+
+    // Try to load regular playlist
+    loadSpy.clear();
+    loadFailedSpy.clear();
+    testFileName = QFINDTESTDATA("testdata/test.pls");
+    playlist.load(QUrl::fromLocalFile(testFileName));
+    QTRY_VERIFY(!loadSpy.isEmpty());
+    QVERIFY(loadFailedSpy.isEmpty());
+    QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+    QCOMPARE(playlist.mediaCount(), 7);
+
+    QCOMPARE(playlist.media(0).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
+    QCOMPARE(playlist.media(1).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
+    testFileName = QFINDTESTDATA("testdata/testfile");
+    QCOMPARE(playlist.media(2).canonicalUrl(),
+             QUrl::fromLocalFile(testFileName));
+    testFileName = QFINDTESTDATA("testdata");
+    QCOMPARE(playlist.media(3).canonicalUrl(),
+             QUrl::fromLocalFile(testFileName + "/testdir/testfile"));
+    QCOMPARE(playlist.media(4).canonicalUrl(), QUrl(QLatin1String("file:///testdir/testfile")));
+    QCOMPARE(playlist.media(5).canonicalUrl(), QUrl(QLatin1String("file://path/name#suffix")));
+    //ensure #2 suffix is not stripped from path
+    testFileName = QFINDTESTDATA("testdata/testfile2#suffix");
+    QCOMPARE(playlist.media(6).canonicalUrl(), QUrl::fromLocalFile(testFileName));
+
+    // Try to load a totem-pl generated playlist
+    // (Format doesn't respect the spec)
+    loadSpy.clear();
+    loadFailedSpy.clear();
+    playlist.clear();
+    testFileName = QFINDTESTDATA("testdata/totem-pl-example.pls");
+    playlist.load(QUrl::fromLocalFile(testFileName));
+    QTRY_VERIFY(!loadSpy.isEmpty());
+    QVERIFY(loadFailedSpy.isEmpty());
+    QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+    QCOMPARE(playlist.mediaCount(), 1);
+    QCOMPARE(playlist.media(0).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
+
+
+    // check ability to load from QNetworkRequest
+    loadSpy.clear();
+    loadFailedSpy.clear();
+    playlist.load(QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.pls"))));
     QTRY_VERIFY(!loadSpy.isEmpty());
     QVERIFY(loadFailedSpy.isEmpty());
 }