diff options
Diffstat (limited to 'src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp')
-rw-r--r-- | src/plugins/multimedia/android/mediaplayer/qandroidmediaplayer.cpp | 124 |
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" |