summaryrefslogtreecommitdiffstats
path: root/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/winrt/qwinrtmediaplayercontrol.cpp')
-rw-r--r--src/plugins/winrt/qwinrtmediaplayercontrol.cpp900
1 files changed, 0 insertions, 900 deletions
diff --git a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp b/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
deleted file mode 100644
index 0ed9f027e..000000000
--- a/src/plugins/winrt/qwinrtmediaplayercontrol.cpp
+++ /dev/null
@@ -1,900 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 "qwinrtmediaplayercontrol.h"
-#include "qwinrtplayerrenderercontrol.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QFile>
-#include <QtCore/qfunctions_winrt.h>
-#include <QtCore/QSize>
-#include <QtCore/QTimerEvent>
-#include <QtCore/QUrl>
-#include <QtMultimedia/QMediaPlaylist>
-#include <QtConcurrent/QtConcurrentRun>
-
-#include <dxgi.h>
-#include <OleAuto.h>
-#include <mfapi.h>
-#include <mfmediaengine.h>
-
-#include <wrl.h>
-using namespace Microsoft::WRL;
-
-QT_BEGIN_NAMESPACE
-
-#define QT_WINRT_MEDIAPLAYER_STREAM_ID "__qtmultimedia_winrt_player_stream"
-
-class MediaEngineNotify;
-class MediaEngineSources;
-class MediaEngineByteStream;
-class QWinRTMediaPlayerControlPrivate
-{
-public:
- QMediaPlayer::State state;
- QMediaPlayer::MediaStatus mediaStatus;
- qint64 duration;
- qint64 position;
- qreal playbackRate;
- int volume;
- bool muted;
- int bufferStatus;
- bool seekable;
- bool hasVideo;
- bool hasAudio;
-
- QMediaContent media;
- QScopedPointer<QIODevice, QWinRTMediaPlayerControlPrivate> stream;
- QWinRTPlayerRendererControl *videoRenderer;
-
- ComPtr<MediaEngineNotify> notifier;
- ComPtr<MediaEngineSources> sources;
- ComPtr<MediaEngineByteStream> streamProvider;
- ComPtr<IMFAttributes> configuration;
- ComPtr<IMFMediaEngineEx> engine;
-
- quint32 resetToken;
- ComPtr<IMFDXGIDeviceManager> manager;
-
- // Automatically delete streams created by the player
- static inline void cleanup(QIODevice *device)
- {
- if (device && device->property(QT_WINRT_MEDIAPLAYER_STREAM_ID).toBool())
- device->deleteLater();
- }
-
- // Allows for deferred cleanup of the engine, which tends to block on shutdown
- static void cleanup(QWinRTMediaPlayerControlPrivate *d);
- static void shutdown(QWinRTMediaPlayerControlPrivate *d);
-};
-
-class MediaEngineNotify : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFMediaEngineNotify>
-{
-public:
- MediaEngineNotify(QWinRTMediaPlayerControl *q_ptr, QWinRTMediaPlayerControlPrivate *d_ptr)
- : q(q_ptr), d(d_ptr)
- {
- }
-
- HRESULT __stdcall EventNotify(DWORD event, DWORD_PTR param1, DWORD param2)
- {
- QMediaPlayer::State newState = d->state;
- QMediaPlayer::MediaStatus newStatus = d->mediaStatus;
-
- switch (event) {
- // Media change events
- case MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA: {
- const bool hasAudio = d->engine->HasAudio();
- if (d->hasAudio != hasAudio) {
- d->hasAudio = hasAudio;
- emit q->audioAvailableChanged(d->hasAudio);
- }
-
- const bool hasVideo = d->engine->HasVideo();
- if (d->hasVideo != hasVideo) {
- d->hasVideo = hasVideo;
- emit q->audioAvailableChanged(d->hasAudio);
- }
-
- if (hasVideo) {
- HRESULT hr;
- DWORD width, height;
- hr = d->engine->GetNativeVideoSize(&width, &height);
- if (FAILED(hr))
- break;
- d->videoRenderer->setSize(QSize(int(width), int(height)));
- }
-
- newStatus = QMediaPlayer::LoadedMedia;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_LOADSTART:
- case MF_MEDIA_ENGINE_EVENT_PROGRESS: {
- newStatus = QMediaPlayer::LoadingMedia;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_CANPLAY:
- d->bufferStatus = 100; // Fired when buffering is not used
- newStatus = d->state == QMediaPlayer::StoppedState ? QMediaPlayer::LoadedMedia
- : QMediaPlayer::BufferedMedia;
- break;
- case MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED:
- case MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED: {
- PROPVARIANT stat;
- HRESULT hr = d->engine->GetStatistics(MF_MEDIA_ENGINE_STATISTIC_BUFFER_PROGRESS, &stat);
- if (SUCCEEDED(hr)) {
- d->bufferStatus = stat.lVal;
- PropVariantClear(&stat);
- }
- newStatus = d->state == QMediaPlayer::StoppedState ? QMediaPlayer::LoadedMedia
- : (d->bufferStatus == 100 ? QMediaPlayer::BufferedMedia : QMediaPlayer::BufferingMedia);
- break;
- }
- //case MF_MEDIA_ENGINE_EVENT_SUSPEND: ???
- //case MF_MEDIA_ENGINE_EVENT_ABORT: ???
- case MF_MEDIA_ENGINE_EVENT_EMPTIED: {
- newState = QMediaPlayer::StoppedState;
- break;
- }
- // Transport controls
- case MF_MEDIA_ENGINE_EVENT_PLAY: {
- // If the media is already loaded, the playing event may not occur after stop
- if (d->mediaStatus != QMediaPlayer::LoadedMedia)
- break;
- Q_FALLTHROUGH();
- }
- case MF_MEDIA_ENGINE_EVENT_PLAYING: {
- newState = QMediaPlayer::PlayingState;
- newStatus = d->bufferStatus < 100 ? QMediaPlayer::BufferingMedia
- : QMediaPlayer::BufferedMedia;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_PAUSE: {
- newState = QMediaPlayer::PausedState;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_STALLED: {
- newStatus = QMediaPlayer::StalledMedia;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_WAITING: {
- newStatus = QMediaPlayer::StalledMedia;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_ENDED: {
- newState = QMediaPlayer::StoppedState;
- newStatus = QMediaPlayer::EndOfMedia;
- break;
- }
- // Media attributes
- case MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE: {
- double duration = d->engine->GetDuration() * 1000;
- if (!qFuzzyCompare(d->duration, duration)) {
- d->duration = qint64(duration);
- emit q->durationChanged(d->duration);
- }
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE: {
- double position = d->engine->GetCurrentTime() * 1000;
- if (!qFuzzyCompare(d->position, position)) {
- d->position = qint64(position);
- emit q->positionChanged(d->position);
- }
- // Stopped state: paused at beginning
- if (qFuzzyIsNull(position) && d->state == QMediaPlayer::PausedState)
- newState = QMediaPlayer::StoppedState;
- break;
- }
- case MF_MEDIA_ENGINE_EVENT_RATECHANGE: {
- double playbackRate = d->engine->GetPlaybackRate();
- if (!qFuzzyCompare(d->playbackRate, playbackRate)) {
- d->playbackRate = playbackRate;
- emit q->playbackRateChanged(d->playbackRate);
- }
- break;
- }
- // Error handling
- case MF_MEDIA_ENGINE_EVENT_ERROR: {
- newState = QMediaPlayer::StoppedState;
- newStatus = QMediaPlayer::InvalidMedia;
- switch (param1) {
- default:
- case MF_MEDIA_ENGINE_ERR_NOERROR:
- newStatus = QMediaPlayer::UnknownMediaStatus;
- emit q->error(QMediaPlayer::ResourceError, qt_error_string(int(param2)));
- break;
- case MF_MEDIA_ENGINE_ERR_ABORTED:
- if (d->mediaStatus == QMediaPlayer::StalledMedia || d->mediaStatus == QMediaPlayer::BufferingMedia)
- d->mediaStatus = QMediaPlayer::LoadedMedia;
- emit q->error(QMediaPlayer::ResourceError, QStringLiteral("The process of fetching the media resource was stopped at the user's request."));
- break;
- case MF_MEDIA_ENGINE_ERR_NETWORK:
- if (d->mediaStatus == QMediaPlayer::StalledMedia || d->mediaStatus == QMediaPlayer::BufferingMedia)
- d->mediaStatus = QMediaPlayer::LoadedMedia;
- emit q->error(QMediaPlayer::NetworkError, QStringLiteral("A network error occurred while fetching the media resource."));
- break;
- case MF_MEDIA_ENGINE_ERR_DECODE:
- emit q->error(QMediaPlayer::FormatError, QStringLiteral("An error occurred while decoding the media resource."));
- break;
- case MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED:
- emit q->error(QMediaPlayer::FormatError, QStringLiteral("The media resource is not supported."));
- break;
- case MF_MEDIA_ENGINE_ERR_ENCRYPTED:
- emit q->error(QMediaPlayer::FormatError, QStringLiteral("An error occurred while encrypting the media resource."));
- break;
- }
- break;
- }
- default:
- break;
- }
-
- if (d->videoRenderer)
- d->videoRenderer->setActive(d->state == QMediaPlayer::PlayingState &&
- d->videoRenderer->size().isValid());
-
- const QMediaPlayer::MediaStatus oldMediaStatus = d->mediaStatus;
- const QMediaPlayer::State oldState = d->state;
- d->mediaStatus = newStatus;
- d->state = newState;
-
- if (d->mediaStatus != oldMediaStatus)
- emit q->mediaStatusChanged(d->mediaStatus);
-
- if (d->state != oldState)
- emit q->stateChanged(d->state);
-
- return S_OK;
- }
-
-private:
- QWinRTMediaPlayerControl *q;
- QWinRTMediaPlayerControlPrivate *d;
-};
-
-class MediaEngineSources : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFMediaEngineSrcElements>
-{
-public:
- MediaEngineSources(QWinRTMediaPlayerControlPrivate *d_ptr)
- : d(d_ptr)
- {
- }
-
- DWORD __stdcall GetLength()
- {
- return 1;
- }
-
- HRESULT __stdcall GetURL(DWORD index, BSTR *url)
- {
- Q_UNUSED(index);
- const QString resourceUrl = d->media.request().url().toString();
- *url = SysAllocString((const OLECHAR *)resourceUrl.utf16());
- return S_OK;
- }
-
- HRESULT __stdcall GetType(DWORD index, BSTR *type)
- {
- Q_UNUSED(index);
- *type = SysAllocString(L"");
- return S_OK;
- }
-
- HRESULT __stdcall GetMedia(DWORD index, BSTR *media)
- {
- Q_UNUSED(index);
- *media = nullptr;
- return S_OK;
- }
-
- HRESULT __stdcall AddElement(BSTR url, BSTR type, BSTR media)
- {
- Q_UNUSED(url);
- Q_UNUSED(type);
- Q_UNUSED(media);
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall RemoveAllElements()
- {
- return E_NOTIMPL;
- }
-
-private:
- QWinRTMediaPlayerControlPrivate *d;
-};
-
-class MediaEngineReadResult : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IUnknown>
-{
-public:
- MediaEngineReadResult(BYTE *bytes, ULONG maxLength)
- : bytes(bytes), maxLength(maxLength) { }
-
- void read(QIODevice *device)
- {
- bytesRead = ULONG(device->read(reinterpret_cast<char *>(bytes), maxLength));
- }
-
- BYTE *bytes;
- ULONG maxLength;
- ULONG bytesRead;
-};
-
-class MediaEngineByteStream : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IMFByteStream>
-{
-public:
- MediaEngineByteStream(QWinRTMediaPlayerControlPrivate *d_ptr)
- : d(d_ptr)
- {
- }
-
- HRESULT __stdcall GetCapabilities(DWORD *capabilities)
- {
- *capabilities |= MFBYTESTREAM_IS_READABLE;
- if (!d->stream->isSequential())
- *capabilities |= MFBYTESTREAM_IS_SEEKABLE;
- return S_OK;
- }
-
- HRESULT __stdcall GetLength(QWORD *length)
- {
- *length = QWORD(d->stream->size());
- return S_OK;
- }
-
- HRESULT __stdcall SetLength(QWORD length)
- {
- Q_UNUSED(length);
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall GetCurrentPosition(QWORD *position)
- {
- *position = QWORD(d->stream->pos());
- return S_OK;
- }
-
- HRESULT __stdcall SetCurrentPosition(QWORD position)
- {
- const qint64 pos = qint64(position);
- if (pos >= d->stream->size()) {
- // MSDN states we should return E_INVALIDARG, but that immediately
- // stops playback and does not play remaining buffers in the queue.
- // For some formats this can cause losing up to 5 seconds of the
- // end of the stream.
- return S_FALSE;
- }
-
- const bool ok = d->stream->seek(pos);
- return ok ? S_OK : S_FALSE;
- }
-
- HRESULT __stdcall IsEndOfStream(BOOL *endOfStream)
- {
- *endOfStream = d->stream->atEnd() ? TRUE : FALSE;
- return S_OK;
- }
-
- HRESULT __stdcall Read(BYTE *bytes, ULONG maxlen, ULONG *bytesRead)
- {
- *bytesRead = ULONG(d->stream->read(reinterpret_cast<char *>(bytes), maxlen));
- return S_OK;
- }
-
- HRESULT __stdcall BeginRead(BYTE *bytes, ULONG maxLength, IMFAsyncCallback *callback, IUnknown *state)
- {
- ComPtr<MediaEngineReadResult> readResult = Make<MediaEngineReadResult>(bytes, maxLength);
- HRESULT hr;
- hr = MFCreateAsyncResult(readResult.Get(), callback, state, &asyncResult);
- RETURN_HR_IF_FAILED("Failed to create read callback result");
- finishRead();
- return S_OK;
- }
-
- HRESULT __stdcall EndRead(IMFAsyncResult *result, ULONG *bytesRead)
- {
- HRESULT hr;
- ComPtr<MediaEngineReadResult> readResult;
- hr = result->GetObject(&readResult);
- RETURN_HR_IF_FAILED("Failed to get read result");
-
- *bytesRead = readResult->bytesRead;
- return S_OK;
- }
-
- HRESULT __stdcall Write(const BYTE *bytes, ULONG maxlen, ULONG *bytesWritten)
- {
- Q_UNUSED(bytes);
- Q_UNUSED(maxlen);
- Q_UNUSED(bytesWritten);
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall BeginWrite(const BYTE *bytes, ULONG maxlen, IMFAsyncCallback *callback, IUnknown *state)
- {
- Q_UNUSED(bytes);
- Q_UNUSED(maxlen);
- Q_UNUSED(callback);
- Q_UNUSED(state);
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall EndWrite(IMFAsyncResult *result, ULONG *bytesWritten)
- {
- Q_UNUSED(result);
- Q_UNUSED(bytesWritten);
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall Seek(MFBYTESTREAM_SEEK_ORIGIN origin, LONGLONG offset, DWORD flags, QWORD *position)
- {
- Q_UNUSED(flags);
-
- qint64 pos = offset;
- if (origin == msoCurrent)
- pos += d->stream->pos();
-
- const bool ok = d->stream->seek(pos);
- *position = QWORD(d->stream->pos());
-
- return ok ? S_OK : E_FAIL;
- }
-
- HRESULT __stdcall Flush()
- {
- return E_NOTIMPL;
- }
-
- HRESULT __stdcall Close()
- {
- if (asyncResult)
- finishRead();
-
- if (d->stream->property(QT_WINRT_MEDIAPLAYER_STREAM_ID).toBool())
- d->stream->close();
-
- return S_OK;
- }
-
- void finishRead()
- {
- if (!asyncResult)
- return;
-
- HRESULT hr;
- ComPtr<MediaEngineReadResult> readResult;
- hr = asyncResult->GetObject(&readResult);
- RETURN_VOID_IF_FAILED("Failed to get read result object");
- readResult->read(d->stream.data());
- hr = MFInvokeCallback(asyncResult.Get());
- RETURN_VOID_IF_FAILED("Failed to invoke read callback");
- asyncResult.Reset();
- }
-
-private:
- QWinRTMediaPlayerControlPrivate *d;
-
- ComPtr<IMFAsyncResult> asyncResult;
-};
-
-void QWinRTMediaPlayerControlPrivate::cleanup(QWinRTMediaPlayerControlPrivate *d)
-{
- QtConcurrent::run(&QWinRTMediaPlayerControlPrivate::shutdown, d);
-}
-
-void QWinRTMediaPlayerControlPrivate::shutdown(QWinRTMediaPlayerControlPrivate *d)
-{
- d->engine->Shutdown();
- delete d;
-}
-
-QWinRTMediaPlayerControl::QWinRTMediaPlayerControl(IMFMediaEngineClassFactory *factory, QObject *parent)
- : QMediaPlayerControl(parent), d_ptr(new QWinRTMediaPlayerControlPrivate)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- d->state = QMediaPlayer::StoppedState;
- d->mediaStatus = QMediaPlayer::NoMedia;
- d->duration = 0;
- d->position = 0;
- d->playbackRate = 1.0;
- d->volume = 100;
- d->bufferStatus = 0;
- d->muted = false;
- d->seekable = false;
- d->hasAudio = false;
- d->hasVideo = false;
- d->videoRenderer = nullptr;
- d->notifier = Make<MediaEngineNotify>(this, d);
-
- HRESULT hr;
- hr = MFCreateDXGIDeviceManager(&d->resetToken, &d->manager);
- RETURN_VOID_IF_FAILED("Failed to create DXGI device manager");
-
- hr = MFCreateAttributes(&d->configuration, 1);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->configuration->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, d->notifier.Get());
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->configuration->SetUnknown(MF_MEDIA_ENGINE_DXGI_MANAGER, d->manager.Get());
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->configuration->SetUINT32(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_B8G8R8A8_UNORM);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IMFMediaEngine> engine;
- hr = factory->CreateInstance(0, d->configuration.Get(), &engine);
- Q_ASSERT_SUCCEEDED(hr);
- hr = engine.As(&d->engine);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = d->engine->SetVolume(1.0);
- Q_ASSERT_SUCCEEDED(hr);
-
- d->sources = Make<MediaEngineSources>(d);
- hr = d->engine->SetSourceElements(d->sources.Get());
- Q_ASSERT_SUCCEEDED(hr);
-
- d->streamProvider = Make<MediaEngineByteStream>(d);
-}
-
-QMediaPlayer::State QWinRTMediaPlayerControl::state() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->state;
-}
-
-QMediaPlayer::MediaStatus QWinRTMediaPlayerControl::mediaStatus() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->mediaStatus;
-}
-
-qint64 QWinRTMediaPlayerControl::duration() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->duration;
-}
-
-qint64 QWinRTMediaPlayerControl::position() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->position;
-}
-
-void QWinRTMediaPlayerControl::setPosition(qint64 position)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->position == position)
- return;
-
- HRESULT hr;
- hr = d->engine->SetCurrentTime(double(position)/1000);
- RETURN_VOID_IF_FAILED("Failed to seek to new position");
-
- d->position = position;
- emit positionChanged(d->position);
-
- if (d->mediaStatus == QMediaPlayer::EndOfMedia) {
- d->mediaStatus = QMediaPlayer::LoadedMedia;
- emit mediaStatusChanged(d->mediaStatus);
- }
-}
-
-int QWinRTMediaPlayerControl::volume() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->volume;
-}
-
-void QWinRTMediaPlayerControl::setVolume(int volume)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->volume == volume)
- return;
-
- HRESULT hr;
- hr = d->engine->SetVolume(double(volume)/100);
- RETURN_VOID_IF_FAILED("Failed to set volume");
-
- d->volume = volume;
- emit volumeChanged(d->volume);
-}
-
-bool QWinRTMediaPlayerControl::isMuted() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->muted;
-}
-
-void QWinRTMediaPlayerControl::setMuted(bool muted)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->muted == muted)
- return;
-
- HRESULT hr;
- hr = d->engine->SetMuted(muted);
- RETURN_VOID_IF_FAILED("Failed to mute volume");
-
- d->muted = muted;
- emit mutedChanged(d->muted);
-}
-
-int QWinRTMediaPlayerControl::bufferStatus() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->bufferStatus;
-}
-
-bool QWinRTMediaPlayerControl::isAudioAvailable() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->hasAudio;
-}
-
-bool QWinRTMediaPlayerControl::isVideoAvailable() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->hasVideo;
-}
-
-bool QWinRTMediaPlayerControl::isSeekable() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->seekable;
-}
-
-QMediaTimeRange QWinRTMediaPlayerControl::availablePlaybackRanges() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return QMediaTimeRange(0, d->duration);
-}
-
-qreal QWinRTMediaPlayerControl::playbackRate() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->playbackRate;
-}
-
-void QWinRTMediaPlayerControl::setPlaybackRate(qreal rate)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (qFuzzyCompare(d->playbackRate, rate))
- return;
-
- HRESULT hr;
- hr = d->engine->SetPlaybackRate(rate);
- RETURN_VOID_IF_FAILED("Failed to set playback rate");
-}
-
-QMediaContent QWinRTMediaPlayerControl::media() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->media;
-}
-
-const QIODevice *QWinRTMediaPlayerControl::mediaStream() const
-{
- Q_D(const QWinRTMediaPlayerControl);
- return d->stream.data();
-}
-
-void QWinRTMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->media == media && d->stream.data() == stream)
- return;
-
- d->media = media;
- d->stream.reset(stream);
- if (d->hasAudio != false) {
- d->hasAudio = false;
- emit audioAvailableChanged(d->hasAudio);
- }
- if (d->hasVideo != false) {
- d->hasVideo = false;
- emit videoAvailableChanged(d->hasVideo);
- }
- if (d->seekable != false) {
- d->seekable = false;
- emit seekableChanged(d->seekable);
- }
- if (d->bufferStatus != 0) {
- d->bufferStatus = 0;
- emit bufferStatusChanged(d->bufferStatus);
- }
- if (d->position != 0) {
- d->position = 0;
- emit positionChanged(d->position);
- }
- if (d->duration != 0) {
- d->duration = 0;
- emit durationChanged(d->duration);
- }
- QMediaPlayer::MediaStatus mediaStatus = media.isNull() ? QMediaPlayer::NoMedia
- : QMediaPlayer::LoadingMedia;
- if (d->mediaStatus != mediaStatus) {
- d->mediaStatus = mediaStatus;
- emit mediaStatusChanged(d->mediaStatus);
- }
- emit mediaChanged(media);
-
- QString urlString = media.request().url().toString();
- if (!d->stream) {
- // If we can read the file via Qt, use the byte stream approach
- if (media.request().url().isLocalFile()) {
- urlString = media.request().url().toLocalFile();
- QScopedPointer<QFile> file(new QFile(urlString));
- if (file->open(QFile::ReadOnly)) {
- file->setProperty(QT_WINRT_MEDIAPLAYER_STREAM_ID, true);
- d->stream.reset(file.take());
- }
- }
- }
-
- HRESULT hr;
- if (d->stream) {
- hr = d->engine->SetSourceFromByteStream(d->streamProvider.Get(),
- reinterpret_cast<BSTR>(urlString.data()));
- if (FAILED(hr)) {
- emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
- return;
- }
- if (d->videoRenderer)
- d->videoRenderer->ensureReady();
- return;
- }
-
- // Let Windows handle all other URLs
- hr = d->engine->SetSource(nullptr); // Resets the byte stream
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->engine->Load();
- if (FAILED(hr))
- emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
-
- if (d->media.isNull() && d->stream.isNull())
- return;
-
- // Resume play/pause/stop
- switch (d->state) {
- case QMediaPlayer::StoppedState:
- stop();
- break;
- case QMediaPlayer::PlayingState:
- play();
- break;
- case QMediaPlayer::PausedState:
- pause();
- break;
- }
-}
-
-void QWinRTMediaPlayerControl::play()
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->state != QMediaPlayer::PlayingState) {
- d->state = QMediaPlayer::PlayingState;
- emit stateChanged(d->state);
- }
-
- if (d->media.isNull() && d->stream.isNull())
- return;
-
- if (d->videoRenderer)
- d->videoRenderer->ensureReady();
-
- HRESULT hr = d->engine->Play();
- if (FAILED(hr)) {
- emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
- return;
- }
-}
-
-void QWinRTMediaPlayerControl::pause()
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (d->state != QMediaPlayer::PausedState) {
- d->state = QMediaPlayer::PausedState;
- emit stateChanged(d->state);
- }
-
- if (d->media.isNull() && d->stream.isNull())
- return;
-
- HRESULT hr;
- hr = d->engine->Pause();
- if (FAILED(hr)) {
- emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
- return;
- }
-}
-
-void QWinRTMediaPlayerControl::stop()
-{
- Q_D(QWinRTMediaPlayerControl);
-
- const QMediaPlayer::MediaStatus oldMediaStatus = d->mediaStatus;
- const QMediaPlayer::State oldState = d->state;
-
- d->state = QMediaPlayer::StoppedState;
-
- if (d->mediaStatus == QMediaPlayer::BufferedMedia
- || d->mediaStatus == QMediaPlayer::BufferingMedia) {
- d->mediaStatus = QMediaPlayer::LoadedMedia;
- }
-
- if (d->mediaStatus != oldMediaStatus)
- emit mediaStatusChanged(d->mediaStatus);
-
- if (d->state != oldState)
- emit stateChanged(d->state);
-
- if (d->media.isNull() && d->stream.isNull())
- return;
-
- setPosition(0);
-
- HRESULT hr;
- hr = d->engine->Pause();
- if (FAILED(hr)) {
- emit error(QMediaPlayer::ResourceError, qt_error_string(hr));
- return;
- }
-}
-
-QVideoRendererControl *QWinRTMediaPlayerControl::videoRendererControl()
-{
- Q_D(QWinRTMediaPlayerControl);
-
- if (!d->videoRenderer) {
- d->videoRenderer = new QWinRTPlayerRendererControl(d->engine.Get(), d->manager.Get(),
- d->resetToken, this);
- }
-
- return d->videoRenderer;
-}
-
-QT_END_NAMESPACE