/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmediaplayer.h"
#include "qvideosurfaces_p.h"
#include "qvideosurfaceoutput_p.h"

#include "qmediaobject_p.h"
#include <qmediaservice.h>
#include <qmediaplayercontrol.h>
#include <qmediaserviceprovider_p.h>
#include <qmediaplaylist.h>
#include <qmediaplaylistcontrol_p.h>
#include <qmediaplaylistsourcecontrol_p.h>
#include <qmedianetworkaccesscontrol.h>
#include <qaudiorolecontrol.h>
#include <qcustomaudiorolecontrol.h>

#include <QtCore/qcoreevent.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qtimer.h>
#include <QtCore/qdebug.h>
#include <QtCore/qpointer.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qtemporaryfile.h>
#include <QDir>

QT_BEGIN_NAMESPACE

/*!
    \class QMediaPlayer
    \brief The QMediaPlayer class allows the playing of a media source.
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_playback

    The QMediaPlayer class is a high level media playback class. It can be used
    to playback such content as songs, movies and internet radio. The content
    to playback is specified as a QMediaContent object, which can be thought of as a
    main or canonical URL with additional information attached. When provided
    with a QMediaContent playback may be able to commence.

    \snippet multimedia-snippets/media.cpp Player

    QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
    for accessing playlist functionality.

    \snippet multimedia-snippets/media.cpp Movie playlist

    Since QMediaPlayer is a QMediaObject, you can use several of the QMediaObject
    functions for things like:

    \list
    \li Accessing the currently playing media's metadata (\l {QMediaObject::metaData()} and \l {QMediaMetaData}{predefined meta-data keys})
    \li Checking to see if the media playback service is currently available (\l {QMediaObject::availability()})
    \endlist

    \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist
*/

static void qRegisterMediaPlayerMetaTypes()
{
    qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
    qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
    qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
}

Q_CONSTRUCTOR_FUNCTION(qRegisterMediaPlayerMetaTypes)

#define MAX_NESTED_PLAYLISTS 16

class QMediaPlayerPrivate : public QMediaObjectPrivate
{
    Q_DECLARE_NON_CONST_PUBLIC(QMediaPlayer)

public:
    QMediaPlayerPrivate()
        : provider(nullptr)
        , control(nullptr)
        , audioRoleControl(nullptr)
        , customAudioRoleControl(nullptr)
        , playlist(nullptr)
#ifndef QT_NO_BEARERMANAGEMENT
        , networkAccessControl(nullptr)
#endif
        , state(QMediaPlayer::StoppedState)
        , status(QMediaPlayer::UnknownMediaStatus)
        , error(QMediaPlayer::NoError)
        , ignoreNextStatusChange(-1)
        , nestedPlaylists(0)
        , hasStreamPlaybackFeature(false)
    {}

    QMediaServiceProvider *provider;
    QMediaPlayerControl* control;
    QAudioRoleControl *audioRoleControl;
    QCustomAudioRoleControl *customAudioRoleControl;
    QString errorString;

    QPointer<QObject> videoOutput;
    QMediaPlaylist *playlist;
#ifndef QT_NO_BEARERMANAGEMENT
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
    QMediaNetworkAccessControl *networkAccessControl;
QT_WARNING_POP
#endif
    QVideoSurfaceOutput surfaceOutput;
    QMediaContent qrcMedia;
    QScopedPointer<QFile> qrcFile;

    QMediaContent rootMedia;
    QMediaContent pendingPlaylist;
    QMediaPlayer::State state;
    QMediaPlayer::MediaStatus status;
    QMediaPlayer::Error error;
    int ignoreNextStatusChange;
    int nestedPlaylists;
    bool hasStreamPlaybackFeature;

    QMediaPlaylist *parentPlaylist(QMediaPlaylist *pls);
    bool isInChain(const QUrl &url);

    void setMedia(const QMediaContent &media, QIODevice *stream = nullptr);

    void setPlaylist(QMediaPlaylist *playlist);
    void setPlaylistMedia();
    void loadPlaylist();
    void disconnectPlaylist();
    void connectPlaylist();

    void _q_stateChanged(QMediaPlayer::State state);
    void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
    void _q_error(int error, const QString &errorString);
    void _q_updateMedia(const QMediaContent&);
    void _q_playlistDestroyed();
    void _q_handleMediaChanged(const QMediaContent&);
    void _q_handlePlaylistLoaded();
    void _q_handlePlaylistLoadFailed();
};

QMediaPlaylist *QMediaPlayerPrivate::parentPlaylist(QMediaPlaylist *pls)
{
    // This function finds a parent playlist for an item in the active chain of playlists.
    // Every item in the chain comes from currentMedia() of its parent.
    // We don't need to travers the whole tree of playlists,
    // but only the subtree of active ones.
    for (QMediaPlaylist *current = rootMedia.playlist(); current && current != pls; current = current->currentMedia().playlist())
        if (current->currentMedia().playlist() == pls)
            return current;
    return nullptr;
}

bool QMediaPlayerPrivate::isInChain(const QUrl &url)
{
    // Check whether a URL is already in the chain of playlists.
    // Also see a comment in parentPlaylist().
    for (QMediaPlaylist *current = rootMedia.playlist(); current && current != playlist; current = current->currentMedia().playlist())
        if (current->currentMedia().request().url() == url) {
            return true;
        }
    return false;
}

void QMediaPlayerPrivate::_q_stateChanged(QMediaPlayer::State ps)
{
    Q_Q(QMediaPlayer);

    // Backend switches into stopped state every time new media is about to be loaded.
    // If media player has a playlist loaded make sure player doesn' stop.
    if (playlist && playlist->currentIndex() != -1 && ps != state && ps == QMediaPlayer::StoppedState) {
        if (control->mediaStatus() == QMediaPlayer::EndOfMedia ||
                control->mediaStatus() == QMediaPlayer::InvalidMedia) {
            // if media player is not stopped, and
            // we have finished playback for the current media,
            // advance to the next item in the playlist
            Q_ASSERT(state != QMediaPlayer::StoppedState);
            playlist->next();
            return;
        } else if (control->mediaStatus() == QMediaPlayer::LoadingMedia) {
            return;
        }
    }

    if (ps != state) {
        state = ps;

        if (ps == QMediaPlayer::PlayingState)
            q->addPropertyWatch("position");
        else
            q->removePropertyWatch("position");

        emit q->stateChanged(ps);
    }
}

void QMediaPlayerPrivate::_q_mediaStatusChanged(QMediaPlayer::MediaStatus s)
{
    Q_Q(QMediaPlayer);

    if (int(s) == ignoreNextStatusChange) {
        ignoreNextStatusChange = -1;
        return;
    }

    if (s != status) {
        status = s;

        switch (s) {
        case QMediaPlayer::StalledMedia:
        case QMediaPlayer::BufferingMedia:
            q->addPropertyWatch("bufferStatus");
            break;
        default:
            q->removePropertyWatch("bufferStatus");
            break;
        }

        emit q->mediaStatusChanged(s);
    }
}

void QMediaPlayerPrivate::_q_error(int error, const QString &errorString)
{
    Q_Q(QMediaPlayer);

    if (error == int(QMediaPlayer::MediaIsPlaylist)) {
        loadPlaylist();
    } else {
        this->error = QMediaPlayer::Error(error);
        this->errorString = errorString;
        emit q->error(this->error);

        if (playlist)
            playlist->next();
    }
}

void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
{
    Q_Q(QMediaPlayer);

    if (!control)
        return;

    // check if the current playlist is a top-level playlist
    Q_ASSERT(playlist);
    if (media.isNull() && playlist != rootMedia.playlist()) {
        // switch back to parent playlist
        QMediaPlaylist *pls = parentPlaylist(playlist);
        Q_ASSERT(pls);
        disconnectPlaylist();
        playlist = pls;
        connectPlaylist();

        Q_ASSERT(!pendingPlaylist.playlist());
        nestedPlaylists--;
        Q_ASSERT(nestedPlaylists >= 0);

        playlist->next();
        return;
    }

    if (media.playlist()) {
        if (nestedPlaylists < MAX_NESTED_PLAYLISTS) {
            nestedPlaylists++;
            Q_ASSERT(!pendingPlaylist.playlist());

            // disconnect current playlist
            disconnectPlaylist();
            // new playlist signals are connected
            // in the call to setPlaylist() in _q_handlePlaylistLoaded()
            playlist = media.playlist();
            emit q->currentMediaChanged(media);
            _q_handlePlaylistLoaded();
            return;
        } else if (playlist) {
            playlist->next();
        }
        return;
    }

    const QMediaPlayer::State currentState = state;

    setMedia(media, nullptr);

    if (!media.isNull()) {
        switch (currentState) {
        case QMediaPlayer::PlayingState:
            control->play();
            break;
        case QMediaPlayer::PausedState:
            control->pause();
            break;
        default:
            break;
        }
    }

    _q_stateChanged(control->state());
}

void QMediaPlayerPrivate::_q_playlistDestroyed()
{
    playlist = nullptr;
    setMedia(QMediaContent(), nullptr);
}

void QMediaPlayerPrivate::setMedia(const QMediaContent &media, QIODevice *stream)
{
    Q_Q(QMediaPlayer);

    if (!control)
        return;

    QScopedPointer<QFile> file;

    // Backends can't play qrc files directly.
    // If the backend supports StreamPlayback, we pass a QFile for that resource.
    // If it doesn't, we copy the data to a temporary file and pass its path.
    if (!media.isNull() && !stream && media.request().url().scheme() == QLatin1String("qrc")) {
        qrcMedia = media;

        file.reset(new QFile(QLatin1Char(':') + media.request().url().path()));
        if (!file->open(QFile::ReadOnly)) {
            QMetaObject::invokeMethod(q, "_q_error", Qt::QueuedConnection,
                                      Q_ARG(int, QMediaPlayer::ResourceError),
                                      Q_ARG(QString, QMediaPlayer::tr("Attempting to play invalid Qt resource")));
            QMetaObject::invokeMethod(q, "_q_mediaStatusChanged", Qt::QueuedConnection,
                                      Q_ARG(QMediaPlayer::MediaStatus, QMediaPlayer::InvalidMedia));
            file.reset();
            // Ignore the next NoMedia status change, we just want to clear the current media
            // on the backend side since we can't load the new one and we want to be in the
            // InvalidMedia status.
            ignoreNextStatusChange = QMediaPlayer::NoMedia;
            control->setMedia(QMediaContent(), nullptr);

        } else if (hasStreamPlaybackFeature) {
            control->setMedia(media, file.data());
        } else {
#if QT_CONFIG(temporaryfile)
#if defined(Q_OS_ANDROID)
            QString tempFileName = QDir::tempPath() + media.request().url().path();
            QDir().mkpath(QFileInfo(tempFileName).path());
            QTemporaryFile *tempFile = QTemporaryFile::createNativeFile(*file);
            if (!tempFile->rename(tempFileName))
                qWarning() << "Could not rename temporary file to:" << tempFileName;
#else
            QTemporaryFile *tempFile = new QTemporaryFile;

            // Preserve original file extension, some backends might not load the file if it doesn't
            // have an extension.
            const QString suffix = QFileInfo(*file).suffix();
            if (!suffix.isEmpty())
                tempFile->setFileTemplate(tempFile->fileTemplate() + QLatin1Char('.') + suffix);

            // Copy the qrc data into the temporary file
            tempFile->open();
            char buffer[4096];
            while (true) {
                qint64 len = file->read(buffer, sizeof(buffer));
                if (len < 1)
                    break;
                tempFile->write(buffer, len);
            }
            tempFile->close();
#endif
            file.reset(tempFile);
            control->setMedia(QMediaContent(QUrl::fromLocalFile(file->fileName())), nullptr);
#else
            qWarning("Qt was built with -no-feature-temporaryfile: playback from resource file is not supported!");
#endif
        }
    } else {
        qrcMedia = QMediaContent();
        control->setMedia(media, stream);
    }

    qrcFile.swap(file); // Cleans up any previous file
}

void QMediaPlayerPrivate::_q_handleMediaChanged(const QMediaContent &media)
{
    Q_Q(QMediaPlayer);

    emit q->currentMediaChanged(qrcMedia.isNull() ? media : qrcMedia);
}

void QMediaPlayerPrivate::setPlaylist(QMediaPlaylist *pls)
{
    disconnectPlaylist();
    playlist = pls;

    setPlaylistMedia();
}

void QMediaPlayerPrivate::setPlaylistMedia()
{
    // This function loads current playlist media into backend.
    // If current media is a playlist, the function recursively
    // loads media from the playlist.
    // It also makes sure the correct playlist signals are connected.
    Q_Q(QMediaPlayer);

    if (playlist) {
        connectPlaylist();
        if (playlist->currentMedia().playlist()) {
            if (nestedPlaylists < MAX_NESTED_PLAYLISTS) {
                emit q->currentMediaChanged(playlist->currentMedia());
                // rewind nested playlist to start
                playlist->currentMedia().playlist()->setCurrentIndex(0);
                nestedPlaylists++;
                setPlaylist(playlist->currentMedia().playlist());
            } else {
                playlist->next();
            }
            return;
        } else {
            // If we've just switched to a new playlist,
            // then last emitted currentMediaChanged was a playlist.
            // Make sure we emit currentMediaChanged if new playlist has
            // the same media as the previous one:
            // sample.m3u
            //      test.wav     -- processed by backend
            //      nested.m3u   -- processed by frontend
            //          test.wav -- processed by backend,
            //                      media is not changed,
            //                      frontend needs to emit currentMediaChanged
            bool isSameMedia = (q->currentMedia() == playlist->currentMedia());
            setMedia(playlist->currentMedia(), nullptr);
            if (isSameMedia) {
                emit q->currentMediaChanged(q->currentMedia());
            }
        }
    } else {
        setMedia(QMediaContent(), nullptr);
    }
}

void QMediaPlayerPrivate::loadPlaylist()
{
    Q_Q(QMediaPlayer);
    Q_ASSERT(pendingPlaylist.isNull());

    // Do not load a playlist if there are more than MAX_NESTED_PLAYLISTS in the chain already,
    // or if the playlist URL is already in the chain, i.e. do not allow recursive playlists and loops.
    if (nestedPlaylists < MAX_NESTED_PLAYLISTS
        && !q->currentMedia().request().url().isEmpty()
        && !isInChain(q->currentMedia().request().url()))
    {
        pendingPlaylist = QMediaContent(new QMediaPlaylist, q->currentMedia().request().url(), true);
        QObject::connect(pendingPlaylist.playlist(), SIGNAL(loaded()), q, SLOT(_q_handlePlaylistLoaded()));
        QObject::connect(pendingPlaylist.playlist(), SIGNAL(loadFailed()), q, SLOT(_q_handlePlaylistLoadFailed()));
        pendingPlaylist.playlist()->load(pendingPlaylist.request());
    } else if (playlist) {
        playlist->next();
    }
}

void QMediaPlayerPrivate::disconnectPlaylist()
{
    Q_Q(QMediaPlayer);
    if (playlist) {
        QObject::disconnect(playlist, SIGNAL(currentMediaChanged(QMediaContent)),
                            q, SLOT(_q_updateMedia(QMediaContent)));
        QObject::disconnect(playlist, SIGNAL(destroyed()), q, SLOT(_q_playlistDestroyed()));
        q->unbind(playlist);
    }
}

void QMediaPlayerPrivate::connectPlaylist()
{
    Q_Q(QMediaPlayer);
    if (playlist) {
        q->bind(playlist);
        QObject::connect(playlist, SIGNAL(currentMediaChanged(QMediaContent)),
                         q, SLOT(_q_updateMedia(QMediaContent)));
        QObject::connect(playlist, SIGNAL(destroyed()), q, SLOT(_q_playlistDestroyed()));
    }
}

void QMediaPlayerPrivate::_q_handlePlaylistLoaded()
{
    Q_Q(QMediaPlayer);

    if (pendingPlaylist.playlist()) {
        Q_ASSERT(!q->currentMedia().playlist());
        // if there is an active playlist
        if (playlist) {
            Q_ASSERT(playlist->currentIndex() >= 0);
            disconnectPlaylist();
            playlist->insertMedia(playlist->currentIndex() + 1, pendingPlaylist);
            playlist->removeMedia(playlist->currentIndex());
            nestedPlaylists++;
        } else {
            Q_ASSERT(!rootMedia.playlist());
            rootMedia = pendingPlaylist;
            emit q->mediaChanged(rootMedia);
        }

        playlist = pendingPlaylist.playlist();
        emit q->currentMediaChanged(pendingPlaylist);
    }
    pendingPlaylist = QMediaContent();

    playlist->next();
    setPlaylistMedia();

    switch (state) {
    case QMediaPlayer::PausedState:
        control->pause();
        break;
    case QMediaPlayer::PlayingState:
        control->play();
        break;
    case QMediaPlayer::StoppedState:
        break;
    }
}

void QMediaPlayerPrivate::_q_handlePlaylistLoadFailed()
{
    pendingPlaylist = QMediaContent();

    if (!control)
        return;

    if (playlist)
        playlist->next();
    else
        setMedia(QMediaContent(), nullptr);
}

static QMediaService *playerService(QMediaPlayer::Flags flags)
{
    QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider();
    if (flags) {
        QMediaServiceProviderHint::Features features;
        if (flags & QMediaPlayer::LowLatency)
            features |= QMediaServiceProviderHint::LowLatencyPlayback;

        if (flags & QMediaPlayer::StreamPlayback)
            features |= QMediaServiceProviderHint::StreamPlayback;

        if (flags & QMediaPlayer::VideoSurface)
            features |= QMediaServiceProviderHint::VideoSurface;

        return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER,
                                        QMediaServiceProviderHint(features));
    }

    return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER);
}


/*!
    Construct a QMediaPlayer instance
    parented to \a parent and with \a flags.
*/

QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags):
    QMediaObject(*new QMediaPlayerPrivate,
                 parent,
                 playerService(flags))
{
    Q_D(QMediaPlayer);

    d->provider = QMediaServiceProvider::defaultServiceProvider();
    if (d->service == nullptr) {
        d->error = ServiceMissingError;
    } else {
        d->control = qobject_cast<QMediaPlayerControl*>(d->service->requestControl(QMediaPlayerControl_iid));
#ifndef QT_NO_BEARERMANAGEMENT
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
        d->networkAccessControl = qobject_cast<QMediaNetworkAccessControl*>(d->service->requestControl(QMediaNetworkAccessControl_iid));
QT_WARNING_POP
#endif
        if (d->control != nullptr) {
            connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SLOT(_q_handleMediaChanged(QMediaContent)));
            connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
            connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
                    SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
            connect(d->control, SIGNAL(error(int,QString)), SLOT(_q_error(int,QString)));

            connect(d->control, &QMediaPlayerControl::durationChanged, this, &QMediaPlayer::durationChanged);
            connect(d->control, &QMediaPlayerControl::positionChanged, this, &QMediaPlayer::positionChanged);
            connect(d->control, &QMediaPlayerControl::audioAvailableChanged, this, &QMediaPlayer::audioAvailableChanged);
            connect(d->control, &QMediaPlayerControl::videoAvailableChanged, this, &QMediaPlayer::videoAvailableChanged);
            connect(d->control, &QMediaPlayerControl::volumeChanged, this, &QMediaPlayer::volumeChanged);
            connect(d->control, &QMediaPlayerControl::mutedChanged, this, &QMediaPlayer::mutedChanged);
            connect(d->control, &QMediaPlayerControl::seekableChanged, this, &QMediaPlayer::seekableChanged);
            connect(d->control, &QMediaPlayerControl::playbackRateChanged, this, &QMediaPlayer::playbackRateChanged);
            connect(d->control, &QMediaPlayerControl::bufferStatusChanged, this, &QMediaPlayer::bufferStatusChanged);

            d->state = d->control->state();
            d->status = d->control->mediaStatus();

            if (d->state == PlayingState)
                addPropertyWatch("position");

            if (d->status == StalledMedia || d->status == BufferingMedia)
                addPropertyWatch("bufferStatus");

            d->hasStreamPlaybackFeature = d->provider->supportedFeatures(d->service).testFlag(QMediaServiceProviderHint::StreamPlayback);

            d->audioRoleControl = qobject_cast<QAudioRoleControl*>(d->service->requestControl(QAudioRoleControl_iid));
            if (d->audioRoleControl) {
                connect(d->audioRoleControl, &QAudioRoleControl::audioRoleChanged,
                        this, &QMediaPlayer::audioRoleChanged);

                d->customAudioRoleControl = qobject_cast<QCustomAudioRoleControl *>(
                        d->service->requestControl(QCustomAudioRoleControl_iid));
                if (d->customAudioRoleControl) {
                    connect(d->customAudioRoleControl,
                            &QCustomAudioRoleControl::customAudioRoleChanged,
                            this,
                            &QMediaPlayer::customAudioRoleChanged);
                }
            }
        }
#ifndef QT_NO_BEARERMANAGEMENT
        if (d->networkAccessControl != nullptr) {
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
            connect(d->networkAccessControl, &QMediaNetworkAccessControl::configurationChanged,
                    this, &QMediaPlayer::networkConfigurationChanged);
QT_WARNING_POP
        }
#endif
    }
}


/*!
    Destroys the player object.
*/

QMediaPlayer::~QMediaPlayer()
{
    Q_D(QMediaPlayer);

    d->disconnectPlaylist();
    // Disconnect everything to prevent notifying
    // when a receiver is already destroyed.
    disconnect();

    if (d->service) {
        if (d->control)
            d->service->releaseControl(d->control);
        if (d->audioRoleControl)
            d->service->releaseControl(d->audioRoleControl);
        if (d->customAudioRoleControl)
            d->service->releaseControl(d->customAudioRoleControl);

        d->provider->releaseService(d->service);
    }
}

QMediaContent QMediaPlayer::media() const
{
    Q_D(const QMediaPlayer);

    return d->rootMedia;
}

/*!
    Returns the stream source of media data.

    This is only valid if a stream was passed to setMedia().

    \sa setMedia()
*/

const QIODevice *QMediaPlayer::mediaStream() const
{
    Q_D(const QMediaPlayer);

    // When playing a resource file, we might have passed a QFile to the backend. Hide it from
    // the user.
    if (d->control && d->qrcMedia.isNull())
        return d->control->mediaStream();

    return nullptr;
}

QMediaPlaylist *QMediaPlayer::playlist() const
{
    Q_D(const QMediaPlayer);

    return d->rootMedia.playlist();
}

QMediaContent QMediaPlayer::currentMedia() const
{
    Q_D(const QMediaPlayer);

    // When playing a resource file, don't return the backend's current media, which
    // can be a temporary file.
    if (!d->qrcMedia.isNull())
        return d->qrcMedia;

    if (d->control)
        return d->control->media();

    return QMediaContent();
}

void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
{
    QMediaContent m(playlist, QUrl(), false);
    setMedia(m);
}

#ifndef QT_NO_BEARERMANAGEMENT
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
/*!
    \obsolete

    Sets the network access points for remote media playback.
    \a configurations contains, in ascending preferential order, a list of
    configuration  that can be used for network access.

    This will invalidate the choice of previous configurations.
*/
void QMediaPlayer::setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations)
{
    Q_D(QMediaPlayer);

    if (d->networkAccessControl)
        d->networkAccessControl->setConfigurations(configurations);
}
QT_WARNING_POP
#endif

QMediaPlayer::State QMediaPlayer::state() const
{
    Q_D(const QMediaPlayer);

    // In case if EndOfMedia status is already received
    // but state is not.
    if (d->control != nullptr
        && d->status == QMediaPlayer::EndOfMedia
        && d->state != d->control->state()) {
        return d->control->state();
    }

    return d->state;
}

QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const
{
    return d_func()->status;
}

qint64 QMediaPlayer::duration() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->duration();

    return -1;
}

qint64 QMediaPlayer::position() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->position();

    return 0;
}

int QMediaPlayer::volume() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->volume();

    return 0;
}

bool QMediaPlayer::isMuted() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->isMuted();

    return false;
}

int QMediaPlayer::bufferStatus() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->bufferStatus();

    return 0;
}

bool QMediaPlayer::isAudioAvailable() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->isAudioAvailable();

    return false;
}

bool QMediaPlayer::isVideoAvailable() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->isVideoAvailable();

    return false;
}

bool QMediaPlayer::isSeekable() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->isSeekable();

    return false;
}

qreal QMediaPlayer::playbackRate() const
{
    Q_D(const QMediaPlayer);

    if (d->control != nullptr)
        return d->control->playbackRate();

    return 0.0;
}

/*!
    Returns the current error state.
*/

QMediaPlayer::Error QMediaPlayer::error() const
{
    return d_func()->error;
}

QString QMediaPlayer::errorString() const
{
    return d_func()->errorString;
}

#ifndef QT_NO_BEARERMANAGEMENT
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
/*!
    \obsolete

    Returns the current network access point  in use.
    If a default contructed QNetworkConfiguration is returned
    this feature is not available or that none of the
    current supplied configurations are in use.
*/
QNetworkConfiguration QMediaPlayer::currentNetworkConfiguration() const
{
    Q_D(const QMediaPlayer);

    if (d->networkAccessControl)
        return d_func()->networkAccessControl->currentConfiguration();

    return QNetworkConfiguration();
}
QT_WARNING_POP
#endif

//public Q_SLOTS:
/*!
    Start or resume playing the current source.
*/

void QMediaPlayer::play()
{
    Q_D(QMediaPlayer);

    if (d->control == nullptr) {
        QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection,
                                    Q_ARG(int, QMediaPlayer::ServiceMissingError),
                                    Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")));
        return;
    }

    //if playlist control is available, the service should advance itself
    if (d->rootMedia.playlist() && !d->rootMedia.playlist()->isEmpty()) {
        // switch to playing state
        if (d->state != QMediaPlayer::PlayingState)
            d->_q_stateChanged(QMediaPlayer::PlayingState);

        if (d->rootMedia.playlist()->currentIndex() == -1) {
            if (d->playlist != d->rootMedia.playlist())
                d->setPlaylist(d->rootMedia.playlist());
            Q_ASSERT(d->playlist == d->rootMedia.playlist());

            emit currentMediaChanged(d->rootMedia);
            d->playlist->setCurrentIndex(0);
        }
    }

    // Reset error conditions
    d->error = NoError;
    d->errorString = QString();

    d->control->play();
}

/*!
    Pause playing the current source.
*/

void QMediaPlayer::pause()
{
    Q_D(QMediaPlayer);

    if (d->control != nullptr)
        d->control->pause();
}

/*!
    Stop playing, and reset the play position to the beginning.
*/

void QMediaPlayer::stop()
{
    Q_D(QMediaPlayer);

    if (d->control != nullptr)
        d->control->stop();

    // If media player didn't stop in response to control.
    // This happens if we have an active playlist and control
    // media status is
    // QMediaPlayer::LoadingMedia, QMediaPlayer::InvalidMedia, or QMediaPlayer::EndOfMedia
    // see QMediaPlayerPrivate::_q_stateChanged()
    if (d->playlist && d->state != QMediaPlayer::StoppedState) {
        d->state = QMediaPlayer::StoppedState;
        removePropertyWatch("position");
        emit stateChanged(QMediaPlayer::StoppedState);
    }
}

void QMediaPlayer::setPosition(qint64 position)
{
    Q_D(QMediaPlayer);

    if (d->control == nullptr)
        return;

    d->control->setPosition(qMax(position, 0ll));
}

void QMediaPlayer::setVolume(int v)
{
    Q_D(QMediaPlayer);

    if (d->control == nullptr)
        return;

    int clamped = qBound(0, v, 100);
    if (clamped == volume())
        return;

    d->control->setVolume(clamped);
}

void QMediaPlayer::setMuted(bool muted)
{
    Q_D(QMediaPlayer);

    if (d->control == nullptr || muted == isMuted())
        return;

    d->control->setMuted(muted);
}

void QMediaPlayer::setPlaybackRate(qreal rate)
{
    Q_D(QMediaPlayer);

    if (d->control != nullptr)
        d->control->setPlaybackRate(rate);
}

/*!
    Sets the current \a media source.

    If a \a stream is supplied; media data will be read from it instead of resolving the media
    source. In this case the url should be provided to resolve additional information
    about the media such as mime type. The \a stream must be open and readable.
    For macOS the \a stream should be also seekable.

    Setting the media to a null QMediaContent will cause the player to discard all
    information relating to the current media source and to cease all I/O operations related
    to that media.

    \note This function returns immediately after recording the specified source of the media.
    It does not wait for the media to finish loading and does not check for errors. Listen for
    the mediaStatusChanged() and error() signals to be notified when the media is loaded and
    when an error occurs during loading.

    Since Qt 5.12.2, the url scheme \c gst-pipeline provides custom pipelines
    for the GStreamer backend.

    \snippet multimedia-snippets/media.cpp Pipeline

    If QAbstractVideoSurface is used as the video output,
    \c qtvideosink can be used as a video sink element directly in the pipeline.
    After that the surface will receive the video frames in QAbstractVideoSurface::present().

    \snippet multimedia-snippets/media.cpp Pipeline Surface

    If QVideoWidget is used as the video output
    and the pipeline contains a video sink element named \c qtvideosink,
    current QVideoWidget will be used to render the video.

    \snippet multimedia-snippets/media.cpp Pipeline Widget

    If the pipeline contains appsrc element, it will be used to push data from \a stream.

    \snippet multimedia-snippets/media.cpp Pipeline appsrc
*/

void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
{
    Q_D(QMediaPlayer);
    stop();

    QMediaContent oldMedia = d->rootMedia;
    d->disconnectPlaylist();
    d->playlist = nullptr;
    d->rootMedia = media;
    d->nestedPlaylists = 0;

    if (oldMedia != media)
        emit mediaChanged(d->rootMedia);

    if (media.playlist()) {
        // reset playlist to the 1st item
        media.playlist()->setCurrentIndex(0);
        d->setPlaylist(media.playlist());
    } else {
        d->setMedia(media, stream);
    }
}

/*!
    \internal
*/

bool QMediaPlayer::bind(QObject *obj)
{
    return QMediaObject::bind(obj);
}

/*!
    \internal
*/

void QMediaPlayer::unbind(QObject *obj)
{
    QMediaObject::unbind(obj);
}

/*!
    Returns the level of support a media player has for a \a mimeType and a set of \a codecs.

    The \a flags argument allows additional requirements such as performance indicators to be
    specified.
*/
QMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
                                               const QStringList& codecs,
                                               Flags flags)
{
    return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
                                                                    mimeType,
                                                                    codecs,
                                                                    flags);
}

/*!
    \deprecated
    Returns a list of MIME types supported by the media player.

    The \a flags argument causes the resultant list to be restricted to MIME types which can be supported
    given additional requirements, such as performance indicators.

    This function may not return useful results on some platforms, and support for a specific file of a
    given mime type is not guaranteed even if the mime type is in general supported.  In addition, in some
    cases this function will need to load all available media plugins and query them for their support, which
    may take some time.
*/
QStringList QMediaPlayer::supportedMimeTypes(Flags flags)
{
    return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
                                                                               flags);
}

/*!
    \fn void QMediaPlayer::setVideoOutput(QVideoWidget* output)

    Attach a QVideoWidget video \a output to the media player.

    If the media player has already video output attached,
    it will be replaced with a new one.
*/
void QMediaPlayer::setVideoOutput(QVideoWidget *output)
{
    Q_D(QMediaPlayer);

    if (d->videoOutput)
        unbind(d->videoOutput);

    // We don't know (in this library) that QVideoWidget inherits QObject
    QObject *outputObject = reinterpret_cast<QObject*>(output);

    d->videoOutput = outputObject && bind(outputObject) ? outputObject : nullptr;
}

/*!
    \fn void QMediaPlayer::setVideoOutput(QGraphicsVideoItem* output)

    Attach a QGraphicsVideoItem video \a output to the media player.

    If the media player has already video output attached,
    it will be replaced with a new one.
*/
void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)
{
    Q_D(QMediaPlayer);

    if (d->videoOutput)
        unbind(d->videoOutput);

    // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
    // but QObject inheritance depends on QObject coming first, so try this out.
    QObject *outputObject = reinterpret_cast<QObject*>(output);

    d->videoOutput = outputObject && bind(outputObject) ? outputObject : nullptr;
}

/*!
    Sets a video \a surface as the video output of a media player.

    If a video output has already been set on the media player the new surface
    will replace it.
*/

void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface)
{
    Q_D(QMediaPlayer);

    d->surfaceOutput.setVideoSurface(surface);

    if (d->videoOutput != &d->surfaceOutput) {
        if (d->videoOutput)
            unbind(d->videoOutput);

        d->videoOutput = nullptr;

        if (surface && bind(&d->surfaceOutput))
            d->videoOutput =  &d->surfaceOutput;
    }  else if (!surface) {
        //unbind the surfaceOutput if null surface is set
        unbind(&d->surfaceOutput);
        d->videoOutput = nullptr;
    }
}

/*!
    \since 5.15
    Sets multiple video surfaces as the video output of a media player.
    This allows the media player to render video frames on different surfaces.

    All video surfaces must support at least one shared \c QVideoFrame::PixelFormat.

    If a video output has already been set on the media player the new surfaces
    will replace it.

    \sa QAbstractVideoSurface::supportedPixelFormats
*/

void QMediaPlayer::setVideoOutput(const QVector<QAbstractVideoSurface *> &surfaces)
{
    setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr);
}

/*! \reimp */
QMultimedia::AvailabilityStatus QMediaPlayer::availability() const
{
    Q_D(const QMediaPlayer);

    if (!d->control)
        return QMultimedia::ServiceMissing;

    return QMediaObject::availability();
}

QAudio::Role QMediaPlayer::audioRole() const
{
    Q_D(const QMediaPlayer);

    if (d->audioRoleControl != nullptr)
        return d->audioRoleControl->audioRole();

    return QAudio::UnknownRole;
}

void QMediaPlayer::setAudioRole(QAudio::Role audioRole)
{
    Q_D(QMediaPlayer);

    if (d->audioRoleControl) {
        if (d->customAudioRoleControl != nullptr && d->audioRoleControl->audioRole() != audioRole) {
            d->customAudioRoleControl->setCustomAudioRole(QString());
        }

        d->audioRoleControl->setAudioRole(audioRole);
    }
}

/*!
    Returns a list of supported audio roles.

    If setting the audio role is not supported, an empty list is returned.

    \since 5.6
    \sa audioRole
*/
QList<QAudio::Role> QMediaPlayer::supportedAudioRoles() const
{
    Q_D(const QMediaPlayer);

    if (d->audioRoleControl)
        return d->audioRoleControl->supportedAudioRoles();

    return QList<QAudio::Role>();
}

QString QMediaPlayer::customAudioRole() const
{
    Q_D(const QMediaPlayer);

    if (audioRole() != QAudio::CustomRole)
        return QString();

    if (d->customAudioRoleControl != nullptr)
        return d->customAudioRoleControl->customAudioRole();

    return QString();
}

void QMediaPlayer::setCustomAudioRole(const QString &audioRole)
{
    Q_D(QMediaPlayer);

    if (d->customAudioRoleControl) {
        Q_ASSERT(d->audioRoleControl);
        setAudioRole(QAudio::CustomRole);
        d->customAudioRoleControl->setCustomAudioRole(audioRole);
    }
}

/*!
    Returns a list of supported custom audio roles. An empty list may
    indicate that the supported custom audio roles aren't known. The
    list may not be complete.

    \since 5.11
    \sa customAudioRole
*/
QStringList QMediaPlayer::supportedCustomAudioRoles() const
{
    Q_D(const QMediaPlayer);

    if (d->customAudioRoleControl)
        return d->customAudioRoleControl->supportedCustomAudioRoles();

    return QStringList();
}

// Enums
/*!
    \enum QMediaPlayer::State

    Defines the current state of a media player.

    \value StoppedState The media player is not playing content, playback will begin from the start
    of the current track.
    \value PlayingState The media player is currently playing content.
    \value PausedState The media player has paused playback, playback of the current track will
    resume from the position the player was paused at.
*/

/*!
    \enum QMediaPlayer::MediaStatus

    Defines the status of a media player's current media.

    \value UnknownMediaStatus The status of the media cannot be determined.
    \value NoMedia The is no current media.  The player is in the StoppedState.
    \value LoadingMedia The current media is being loaded. The player may be in any state.
    \value LoadedMedia The current media has been loaded. The player is in the StoppedState.
    \value StalledMedia Playback of the current media has stalled due to insufficient buffering or
    some other temporary interruption.  The player is in the PlayingState or PausedState.
    \value BufferingMedia The player is buffering data but has enough data buffered for playback to
    continue for the immediate future.  The player is in the PlayingState or PausedState.
    \value BufferedMedia The player has fully buffered the current media.  The player is in the
    PlayingState or PausedState.
    \value EndOfMedia Playback has reached the end of the current media.  The player is in the
    StoppedState.
    \value InvalidMedia The current media cannot be played.  The player is in the StoppedState.
*/

/*!
    \enum QMediaPlayer::Error

    Defines a media player error condition.

    \value NoError No error has occurred.
    \value ResourceError A media resource couldn't be resolved.
    \value FormatError The format of a media resource isn't (fully) supported.  Playback may still
    be possible, but without an audio or video component.
    \value NetworkError A network error occurred.
    \value AccessDeniedError There are not the appropriate permissions to play a media resource.
    \value ServiceMissingError A valid playback service was not found, playback cannot proceed.
    \omitvalue MediaIsPlaylist
*/

// Signals
/*!
    \fn QMediaPlayer::error(QMediaPlayer::Error error)

    Signals that an \a error condition has occurred.

    \sa errorString()
*/

/*!
    \fn void QMediaPlayer::stateChanged(State state)

    Signal the \a state of the Player object has changed.
*/

/*!
    \fn QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)

    Signals that the \a status of the current media has changed.

    \sa mediaStatus()
*/

/*!
    \fn void QMediaPlayer::mediaChanged(const QMediaContent &media);

    Signals that the media source has been changed to \a media.

    \sa media(), currentMediaChanged()
*/

/*!
    \fn void QMediaPlayer::currentMediaChanged(const QMediaContent &media);

    Signals that the current playing content has been changed to \a media.

    \sa currentMedia(), mediaChanged()
*/

/*!
    \fn void QMediaPlayer::playbackRateChanged(qreal rate);

    Signals the playbackRate has changed to \a rate.
*/

/*!
    \fn void QMediaPlayer::seekableChanged(bool seekable);

    Signals the \a seekable status of the player object has changed.
*/

/*!
    \fn void QMediaPlayer::audioRoleChanged(QAudio::Role role)

    Signals that the audio \a role of the media player has changed.

    \since 5.6
*/

/*!
    \fn void QMediaPlayer::customAudioRoleChanged(const QString &role)

    Signals that the audio \a role of the media player has changed.

    \since 5.11
*/

// Properties
/*!
    \property QMediaPlayer::state
    \brief the media player's playback state.

    By default this property is QMediaPlayer::Stopped

    \sa mediaStatus(), play(), pause(), stop()
*/

/*!
    \property QMediaPlayer::error
    \brief a string describing the last error condition.

    \sa error()
*/

/*!
    \property QMediaPlayer::media
    \brief the active media source being used by the player object.

    The player object will use the QMediaContent for selection of the content to
    be played.

    By default this property has a null QMediaContent.

    Setting this property to a null QMediaContent will cause the player to discard all
    information relating to the current media source and to cease all I/O operations related
    to that media.

    \sa QMediaContent, currentMedia()
*/

/*!
    \property QMediaPlayer::currentMedia
    \brief the current active media content being played by the player object.
    This value could be different from QMediaPlayer::media property if a playlist is used.
    In this case currentMedia indicates the current media content being processed
    by the player, while QMediaPlayer::media property contains the original playlist.

    \sa QMediaContent, media()
*/

/*!
    \property QMediaPlayer::playlist
    \brief the media playlist being used by the player object.

    The player object will use the current playlist item for selection of the content to
    be played.

    By default this property is set to null.

    If the media playlist is used as a source, QMediaPlayer::currentMedia is updated with
    a current playlist item. The current source should be selected with
    QMediaPlaylist::setCurrentIndex(int) instead of QMediaPlayer::setMedia(),
    otherwise the current playlist will be discarded.

    \sa QMediaContent
*/


/*!
    \property QMediaPlayer::mediaStatus
    \brief the status of the current media stream.

    The stream status describes how the playback of the current stream is
    progressing.

    By default this property is QMediaPlayer::NoMedia

    \sa state
*/

/*!
    \property QMediaPlayer::duration
    \brief the duration of the current media.

    The value is the total playback time in milliseconds of the current media.
    The value may change across the life time of the QMediaPlayer object and
    may not be available when initial playback begins, connect to the
    durationChanged() signal to receive status notifications.
*/

/*!
    \property QMediaPlayer::position
    \brief the playback position of the current media.

    The value is the current playback position, expressed in milliseconds since
    the beginning of the media. Periodically changes in the position will be
    indicated with the signal positionChanged(), the interval between updates
    can be set with QMediaObject's method setNotifyInterval().
*/

/*!
    \property QMediaPlayer::volume
    \brief the current playback volume.

    The playback volume is scaled linearly, ranging from \c 0 (silence) to \c 100 (full volume).
    Values outside this range will be clamped.

    By default the volume is \c 100.

    UI volume controls should usually be scaled nonlinearly. For example, using a logarithmic scale
    will produce linear changes in perceived loudness, which is what a user would normally expect
    from a volume control. See QAudio::convertVolume() for more details.
*/

/*!
    \property QMediaPlayer::muted
    \brief the muted state of the current media.

    The value will be true if the playback volume is muted; otherwise false.
*/

/*!
    \property QMediaPlayer::bufferStatus
    \brief the percentage of the temporary buffer filled before playback begins or resumes, from
    \c 0 (empty) to \c 100 (full).

    When the player object is buffering; this property holds the percentage of
    the temporary buffer that is filled. The buffer will need to reach 100%
    filled before playback can start or resume, at which time mediaStatus() will return
    BufferedMedia or BufferingMedia. If the value is anything lower than \c 100, mediaStatus() will
    return StalledMedia.

    \sa mediaStatus()
*/

/*!
    \property QMediaPlayer::audioAvailable
    \brief the audio availabilty status for the current media.

    As the life time of QMediaPlayer can be longer than the playback of one
    QMediaContent, this property may change over time, the
    audioAvailableChanged signal can be used to monitor it's status.
*/

/*!
    \property QMediaPlayer::videoAvailable
    \brief the video availability status for the current media.

    If available, the QVideoWidget class can be used to view the video. As the
    life time of QMediaPlayer can be longer than the playback of one
    QMediaContent, this property may change over time, the
    videoAvailableChanged signal can be used to monitor it's status.

    \sa QVideoWidget, QMediaContent
*/

/*!
    \property QMediaPlayer::seekable
    \brief the seek-able status of the current media

    If seeking is supported this property will be true; false otherwise. The
    status of this property may change across the life time of the QMediaPlayer
    object, use the seekableChanged signal to monitor changes.
*/

/*!
    \property QMediaPlayer::playbackRate
    \brief the playback rate of the current media.

    This value is a multiplier applied to the media's standard play rate. By
    default this value is 1.0, indicating that the media is playing at the
    standard pace. Values higher than 1.0 will increase the rate of play.
    Values less than zero can be set and indicate the media should rewind at the
    multiplier of the standard pace.

    Not all playback services support change of the playback rate. It is
    framework defined as to the status and quality of audio and video
    while fast forwarding or rewinding.
*/

/*!
    \property QMediaPlayer::audioRole
    \brief the role of the audio stream played by the media player.

    It can be set to specify the type of audio being played, allowing the system to make
    appropriate decisions when it comes to volume, routing or post-processing.

    The audio role must be set before calling setMedia().

    customAudioRole is cleared when this property is set to anything other than
    QAudio::CustomRole.

    \since 5.6
    \sa supportedAudioRoles()
*/

/*!
    \property QMediaPlayer::customAudioRole
    \brief the role of the audio stream played by the media player.

    It can be set to specify the type of audio being played when the backend supports
    audio roles unknown to Qt. Specifying a role allows the system to make appropriate
    decisions when it comes to volume, routing or post-processing.

    The audio role must be set before calling setMedia().

    audioRole is set to QAudio::CustomRole when this property is set.

    \since 5.11
    \sa supportedCustomAudioRoles()
*/

/*!
    \fn void QMediaPlayer::durationChanged(qint64 duration)

    Signal the duration of the content has changed to \a duration, expressed in milliseconds.
*/

/*!
    \fn void QMediaPlayer::positionChanged(qint64 position)

    Signal the position of the content has changed to \a position, expressed in
    milliseconds.
*/

/*!
    \fn void QMediaPlayer::volumeChanged(int volume)

    Signal the playback volume has changed to \a volume.
*/

/*!
    \fn void QMediaPlayer::mutedChanged(bool muted)

    Signal the mute state has changed to \a muted.
*/

/*!
    \fn void QMediaPlayer::videoAvailableChanged(bool videoAvailable)

    Signal the availability of visual content has changed to \a videoAvailable.
*/

/*!
    \fn void QMediaPlayer::audioAvailableChanged(bool available)

    Signals the availability of audio content has changed to \a available.
*/

/*!
    \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)

    Signal the amount of the local buffer filled as a percentage by \a percentFilled.
*/

/*!
   \fn void QMediaPlayer::networkConfigurationChanged(const QNetworkConfiguration &configuration)
   \obsolete

    Signal that the active in use network access point  has been changed to \a configuration and all subsequent network access will use this \a configuration.
*/

/*!
    \enum QMediaPlayer::Flag

    \value LowLatency       The player is expected to be used with simple audio formats,
            but playback should start without significant delay.
            Such playback service can be used for beeps, ringtones, etc.

    \value StreamPlayback   The player is expected to play QIODevice based streams.
            If passed to QMediaPlayer constructor, the service supporting
            streams playback will be chosen.

    \value VideoSurface     The player is expected to be able to render to a
            QAbstractVideoSurface \l {setVideoOutput()}{output}.
*/

QT_END_NAMESPACE

#include "moc_qmediaplayer.cpp"
