summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp')
-rw-r--r--src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp124
1 files changed, 43 insertions, 81 deletions
diff --git a/src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp b/src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp
index 01a57c298..b257a8986 100644
--- a/src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp
+++ b/src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qandroidmediaplayer_p.h"
#include "androidmediaplayer_p.h"
@@ -44,11 +8,12 @@
#include "qandroidaudiooutput_p.h"
#include "qaudiooutput.h"
+#include <private/qplatformvideosink_p.h>
#include <qloggingcategory.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcMediaPlayer, "qt.multimedia.mediaplayer.android")
+static Q_LOGGING_CATEGORY(lcMediaPlayer, "qt.multimedia.mediaplayer.android")
class StateChangeNotifier
{
@@ -84,6 +49,8 @@ QAndroidMediaPlayer::QAndroidMediaPlayer(QMediaPlayer *parent)
mMediaPlayer(new AndroidMediaPlayer),
mState(AndroidMediaPlayer::Uninitialized)
{
+ // Set seekable to True by default. It changes if MEDIA_INFO_NOT_SEEKABLE is received
+ seekableChanged(true);
connect(mMediaPlayer, &AndroidMediaPlayer::bufferingChanged, this,
&QAndroidMediaPlayer::onBufferingChanged);
connect(mMediaPlayer, &AndroidMediaPlayer::info, this, &QAndroidMediaPlayer::onInfo);
@@ -102,6 +69,9 @@ QAndroidMediaPlayer::QAndroidMediaPlayer(QMediaPlayer *parent)
QAndroidMediaPlayer::~QAndroidMediaPlayer()
{
+ if (m_videoSink)
+ disconnect(m_videoSink->platformVideoSink(), nullptr, this, nullptr);
+
mMediaPlayer->disconnect();
mMediaPlayer->release();
delete mMediaPlayer;
@@ -249,43 +219,24 @@ void QAndroidMediaPlayer::updateAvailablePlaybackRanges()
qreal QAndroidMediaPlayer::playbackRate() const
{
- if (mHasPendingPlaybackRate ||
- (mState & (AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted
- | AndroidMediaPlayer::Error)) == 0) {
- return mPendingPlaybackRate;
- }
-
- return mMediaPlayer->playbackRate();
+ return mCurrentPlaybackRate;
}
void QAndroidMediaPlayer::setPlaybackRate(qreal rate)
{
- if ((mState & (AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted
- | AndroidMediaPlayer::Error)) == 0) {
- if (mPendingPlaybackRate != rate) {
- mPendingPlaybackRate = rate;
+ if (mState != AndroidMediaPlayer::Started) {
+ // If video isn't playing, changing speed rate may start it automatically
+ // It need to be postponed
+ if (mCurrentPlaybackRate != rate) {
+ mCurrentPlaybackRate = rate;
mHasPendingPlaybackRate = true;
Q_EMIT playbackRateChanged(rate);
}
return;
}
- bool succeeded = mMediaPlayer->setPlaybackRate(rate);
-
- if (mHasPendingPlaybackRate) {
- mHasPendingPlaybackRate = false;
- mPendingPlaybackRate = qreal(1.0);
- if (!succeeded)
- Q_EMIT playbackRateChanged(playbackRate());
- } else if (succeeded) {
+ if (mMediaPlayer->setPlaybackRate(rate)) {
+ mCurrentPlaybackRate = rate;
Q_EMIT playbackRateChanged(rate);
}
}
@@ -325,7 +276,8 @@ void QAndroidMediaPlayer::setMedia(const QUrl &mediaContent,
if (mVideoSize.isValid() && mVideoOutput)
mVideoOutput->setVideoSize(mVideoSize);
- if ((mMediaPlayer->display() == 0) && mVideoOutput)
+ if (mVideoOutput &&
+ (mMediaPlayer->display() == 0 || mVideoOutput->shouldTextureBeUpdated()))
mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
mMediaPlayer->setDataSource(QNetworkRequest(mediaContent));
mMediaPlayer->prepareAsync();
@@ -344,6 +296,9 @@ void QAndroidMediaPlayer::setVideoSink(QVideoSink *sink)
if (m_videoSink == sink)
return;
+ if (m_videoSink)
+ disconnect(m_videoSink->platformVideoSink(), nullptr, this, nullptr);
+
m_videoSink = sink;
if (!m_videoSink) {
@@ -356,16 +311,17 @@ void QAndroidMediaPlayer::setVideoSink(QVideoSink *sink)
mMediaPlayer->setDisplay(nullptr);
}
- mVideoOutput = new QAndroidTextureVideoOutput(this);
+ mVideoOutput = new QAndroidTextureVideoOutput(sink, this);
connect(mVideoOutput, &QAndroidTextureVideoOutput::readyChanged, this,
&QAndroidMediaPlayer::onVideoOutputReady);
connect(mMediaPlayer, &AndroidMediaPlayer::timedTextChanged, mVideoOutput,
&QAndroidTextureVideoOutput::setSubtitle);
- mVideoOutput->setSurface(sink);
-
if (mVideoOutput->isReady())
mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
+
+ connect(m_videoSink->platformVideoSink(), &QPlatformVideoSink::rhiChanged, this, [&]()
+ { mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); });
}
void QAndroidMediaPlayer::setAudioOutput(QPlatformAudioOutput *output)
@@ -416,6 +372,14 @@ void QAndroidMediaPlayer::play()
updateAudioDevice();
+ if (mHasPendingPlaybackRate) {
+ mHasPendingPlaybackRate = false;
+ if (mMediaPlayer->setPlaybackRate(mCurrentPlaybackRate))
+ return;
+ mCurrentPlaybackRate = mMediaPlayer->playbackRate();
+ Q_EMIT playbackRateChanged(mCurrentPlaybackRate);
+ }
+
mMediaPlayer->play();
}
@@ -437,8 +401,6 @@ void QAndroidMediaPlayer::pause()
mPendingState = QMediaPlayer::PausedState;
return;
}
- if (mVideoOutput)
- mVideoOutput->renderFrame();
const qint64 currentPosition = mMediaPlayer->getCurrentPosition();
setPosition(currentPosition);
@@ -462,17 +424,16 @@ void QAndroidMediaPlayer::stop()
return;
}
+ if (mCurrentPlaybackRate != 1.)
+ // Playback rate need to by reapplied
+ mHasPendingPlaybackRate = true;
+
if (mVideoOutput)
mVideoOutput->stop();
mMediaPlayer->stop();
}
-bool QAndroidMediaPlayer::isSeekable() const
-{
- return true;
-}
-
void QAndroidMediaPlayer::onInfo(qint32 what, qint32 extra)
{
StateChangeNotifier notifier(this);
@@ -552,7 +513,9 @@ void QAndroidMediaPlayer::onError(qint32 what, qint32 extra)
setMediaStatus(QMediaPlayer::InvalidMedia);
break;
case AndroidMediaPlayer::MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN:
- errorString += QLatin1String(" (Unknown error/Insufficient resources)");
+ errorString += mMediaContent.scheme() == QLatin1String("rtsp")
+ ? QLatin1String(" (Unknown error/Insufficient resources or RTSP may not be supported)")
+ : QLatin1String(" (Unknown error/Insufficient resources)");
error = QMediaPlayer::ResourceError;
break;
}
@@ -685,7 +648,6 @@ void QAndroidMediaPlayer::onStateChanged(qint32 state)
mMediaPlayer->setDisplay(0);
if (mVideoOutput) {
mVideoOutput->stop();
- mVideoOutput->reset();
}
}
}
@@ -981,8 +943,6 @@ void QAndroidMediaPlayer::flushPendingStates()
setVolume(mPendingVolume);
if (mPendingMute != -1)
setMuted((mPendingMute == 1));
- if (mHasPendingPlaybackRate)
- setPlaybackRate(mPendingPlaybackRate);
switch (newState) {
case QMediaPlayer::PlayingState:
@@ -1035,3 +995,5 @@ void QAndroidMediaPlayer::updateTrackInfo()
}
QT_END_NAMESPACE
+
+#include "moc_qandroidmediaplayer_p.cpp"