From 32138eace372f5c2defdcfb2f69e3b31621f7b80 Mon Sep 17 00:00:00 2001 From: Piotr Srebrny Date: Thu, 22 Sep 2022 12:29:20 +0200 Subject: Remove QFFmpegAudioDecoder and QFFmpegMediaPlayer from QFFmpeg::Decoder This patch removes unnecessary dependencies from QFFmpeg::Decoder on QFFmpegAudioDecoder and QFFmpegMediaPlayer. Pick-to: 6.4 Change-Id: I73116b6111aca0616de83a029a95db7bd7421aaf Reviewed-by: Lars Knoll Reviewed-by: Artem Dyomin --- .../multimedia/ffmpeg/qffmpegaudiodecoder.cpp | 27 ++++++++- .../multimedia/ffmpeg/qffmpegaudiodecoder_p.h | 1 + src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp | 66 +++------------------- src/plugins/multimedia/ffmpeg/qffmpegdecoder_p.h | 24 ++------ .../multimedia/ffmpeg/qffmpegmediaplayer.cpp | 27 +++++++-- .../multimedia/ffmpeg/qffmpegmediaplayer_p.h | 5 ++ 6 files changed, 67 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder.cpp index d7ef97dc8..4dff93d12 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder.cpp @@ -38,8 +38,7 @@ class AudioDecoder : public Decoder { Q_OBJECT public: - explicit AudioDecoder(QFFmpegAudioDecoder *audioDecoder) - : Decoder(audioDecoder) + explicit AudioDecoder(QFFmpegAudioDecoder *audioDecoder) : Decoder(), audioDecoder(audioDecoder) {} void setup(const QAudioFormat &format) @@ -63,6 +62,7 @@ Q_SIGNALS: void isAtEnd(); private: + QFFmpegAudioDecoder *audioDecoder = nullptr; QAudioFormat m_format; }; @@ -175,6 +175,7 @@ void QFFmpegAudioDecoder::start() if (error() != QAudioDecoder::NoError) goto error; + connect(decoder, &QFFmpeg::Decoder::errorOccured, this, &QFFmpegAudioDecoder::errorSignal); durationChanged(duration()); setIsDecoding(true); return; @@ -237,6 +238,28 @@ void QFFmpegAudioDecoder::done() finished(); } +void QFFmpegAudioDecoder::errorSignal(int err, const QString &errorString) +{ + // unfortunately the error enums for QAudioDecoder and QMediaPlayer aren't identical. + // Map them. + switch (QMediaPlayer::Error(err)) { + case QMediaPlayer::NoError: + error(QAudioDecoder::NoError, errorString); + break; + case QMediaPlayer::ResourceError: + error(QAudioDecoder::ResourceError, errorString); + break; + case QMediaPlayer::FormatError: + error(QAudioDecoder::FormatError, errorString); + break; + case QMediaPlayer::NetworkError: + // fall through, Network error doesn't exist in QAudioDecoder + case QMediaPlayer::AccessDeniedError: + error(QAudioDecoder::AccessDeniedError, errorString); + break; + } +} + QT_END_NAMESPACE #include "qffmpegaudiodecoder.moc" diff --git a/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder_p.h b/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder_p.h index 252784984..0196f88a7 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpegaudiodecoder_p.h @@ -53,6 +53,7 @@ public: public Q_SLOTS: void newAudioBuffer(const QAudioBuffer &b); void done(); + void errorSignal(int err, const QString &errorString); private: QUrl m_url; diff --git a/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp index bcefcaeb2..92de9d86b 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp @@ -126,7 +126,7 @@ StreamDecoder *Demuxer::addStream(int streamIndex) QMutexLocker locker(&mutex); auto maybeCodec = Codec::create(avStream); if (!maybeCodec) { - decoder->error(QMediaPlayer::FormatError, "Cannot open codec; " + maybeCodec.error()); + decoder->errorOccured(QMediaPlayer::FormatError, "Cannot open codec; " + maybeCodec.error()); return nullptr; } auto *stream = new StreamDecoder(this, maybeCodec.value()); @@ -858,7 +858,6 @@ void AudioRenderer::loop() return; } eos.storeRelease(false); - if (!audioSink) updateOutput(frame.codec()); @@ -914,7 +913,6 @@ void AudioRenderer::updateAudio() void AudioRenderer::setSoundVolume(float volume) { QMutexLocker locker(&mutex); - if (audioSink) audioSink->setVolume(volume); } @@ -1041,11 +1039,11 @@ void Decoder::setMedia(const QUrl &media, QIODevice *stream) QByteArray url = media.toEncoded(QUrl::PreferLocalFile); AVFormatContext *context = nullptr; - if (stream) { if (!stream->isOpen()) { if (!stream->open(QIODevice::ReadOnly)) { - emitError(QMediaPlayer::ResourceError, QLatin1String("Could not open source device.")); + emit errorOccured(QMediaPlayer::ResourceError, + QLatin1String("Could not open source device.")); return; } } @@ -1065,13 +1063,14 @@ void Decoder::setMedia(const QUrl &media, QIODevice *stream) else if (ret == AVERROR(EINVAL)) code = QMediaPlayer::FormatError; - emitError(code, QMediaPlayer::tr("Could not open file")); + emit errorOccured(code, QMediaPlayer::tr("Could not open file")); return; } ret = avformat_find_stream_info(context, nullptr); if (ret < 0) { - emitError(QMediaPlayer::FormatError, QMediaPlayer::tr("Could not find stream information for media file")); + emit errorOccured(QMediaPlayer::FormatError, + QMediaPlayer::tr("Could not find stream information for media file")); avformat_free_context(context); return; } @@ -1117,39 +1116,6 @@ void Decoder::setActiveTrack(QPlatformMediaPlayer::TrackType type, int streamNum changeAVTrack(type); } -void Decoder::error(int errorCode, const QString &errorString) -{ - QMetaObject::invokeMethod(this, "emitError", Q_ARG(int, errorCode), Q_ARG(QString, errorString)); -} - -void Decoder::emitError(int error, const QString &errorString) -{ - if (player) - player->error(error, errorString); - else if (audioDecoder) { - // unfortunately the error enums for QAudioDecoder and QMediaPlayer aren't identical. - // Map them. - switch (QMediaPlayer::Error(error)) { - case QMediaPlayer::NoError: - error = QAudioDecoder::NoError; - break; - case QMediaPlayer::ResourceError: - error = QAudioDecoder::ResourceError; - break; - case QMediaPlayer::FormatError: - error = QAudioDecoder::FormatError; - break; - case QMediaPlayer::NetworkError: - // fall through, Network error doesn't exist in QAudioDecoder - case QMediaPlayer::AccessDeniedError: - error = QAudioDecoder::AccessDeniedError; - break; - } - - audioDecoder->error(error, errorString); - } -} - void Decoder::setState(QMediaPlayer::PlaybackState state) { if (m_state == state) @@ -1164,7 +1130,6 @@ void Decoder::setState(QMediaPlayer::PlaybackState state) seek(0); if (videoSink) videoSink->setVideoFrame({}); - updateCurrentTime(0); qCDebug(qLcDecoder) << "Decoder::stop: done"; break; case QMediaPlayer::PausedState: @@ -1213,7 +1178,7 @@ void Decoder::setVideoSink(QVideoSink *sink) } } else if (!videoRenderer) { videoRenderer = new VideoRenderer(this, sink); - connect(audioRenderer, &Renderer::atEnd, this, &Decoder::streamAtEnd); + connect(videoRenderer, &Renderer::atEnd, this, &Decoder::streamAtEnd); videoRenderer->start(); StreamDecoder *stream = demuxer->addStream(avStreamIndex(QPlatformMediaPlayer::VideoStream)); videoRenderer->setStream(stream); @@ -1278,8 +1243,6 @@ void Decoder::seek(qint64 pos) pos = qBound(0, pos, m_duration); demuxer->seek(pos); clockController.syncTo(pos); - if (player) - player->positionChanged(pos/1000); demuxer->wake(); if (m_state == QMediaPlayer::PausedState) triggerStep(); @@ -1290,12 +1253,6 @@ void Decoder::setPlaybackRate(float rate) clockController.setPlaybackRate(rate); } -void Decoder::updateCurrentTime(qint64 time) -{ - if (player) - player->positionChanged(time/1000); -} - void Decoder::streamAtEnd() { if (audioRenderer && !audioRenderer->isAtEnd()) @@ -1303,13 +1260,8 @@ void Decoder::streamAtEnd() if (videoRenderer && !videoRenderer->isAtEnd()) return; pause(); - // take a local copy, as the signals below could lead to this object being deleted - auto *p = player; - if (p) { - p->positionChanged(m_duration/1000); - p->stateChanged(QMediaPlayer::StoppedState); - p->mediaStatusChanged(QMediaPlayer::EndOfMedia); - } + + emit endOfStream(); } QT_END_NAMESPACE diff --git a/src/plugins/multimedia/ffmpeg/qffmpegdecoder_p.h b/src/plugins/multimedia/ffmpeg/qffmpegdecoder_p.h index 235080418..69edf26b4 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegdecoder_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpegdecoder_p.h @@ -151,14 +151,6 @@ class Decoder : public QObject Q_OBJECT public: Decoder(); - Decoder(QFFmpegMediaPlayer *player) - : player(player) - { - } - Decoder(QFFmpegAudioDecoder *decoder) - : audioDecoder(decoder) - { - } ~Decoder(); void setMedia(const QUrl &media, QIODevice *stream); @@ -193,12 +185,12 @@ public: return m_isSeekable; } - // threadsafe - void error(int errorCode, const QString &errorString); +signals: + void endOfStream(); + void errorOccured(int error, const QString &errorString); + void positionChanged(qint64 time); -public Q_SLOTS: - void emitError(int error, const QString &errorString); - void updateCurrentTime(qint64 time); +public slots: void streamAtEnd(); public: @@ -217,21 +209,15 @@ private: protected: friend QFFmpegMediaPlayer; - QFFmpegMediaPlayer *player = nullptr; - QFFmpegAudioDecoder *audioDecoder = nullptr; - QMediaPlayer::PlaybackState m_state = QMediaPlayer::StoppedState; bool m_isSeekable = false; Demuxer *demuxer = nullptr; QVideoSink *videoSink = nullptr; Renderer *videoRenderer = nullptr; - QPlatformAudioOutput *audioOutput = nullptr; Renderer *audioRenderer = nullptr; - bool playing = false; - QList m_streamMap[QPlatformMediaPlayer::NTrackTypes]; int m_requestedStreams[QPlatformMediaPlayer::NTrackTypes] = { -1, -1, -1 }; qint64 m_duration = 0; diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer.cpp b/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer.cpp index e99d25548..5e6062f42 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer.cpp @@ -47,8 +47,10 @@ qint64 QFFmpegMediaPlayer::duration() const void QFFmpegMediaPlayer::setPosition(qint64 position) { - if (decoder) - decoder->seek(position*1000); + if (decoder) { + decoder->seek(position * 1000); + updatePosition(); + } if (state() == QMediaPlayer::StoppedState) mediaStatusChanged(QMediaPlayer::LoadedMedia); } @@ -58,6 +60,13 @@ void QFFmpegMediaPlayer::updatePosition() positionChanged(decoder ? decoder->clockController.currentTime() / 1000 : 0); } +void QFFmpegMediaPlayer::endOfStream() +{ + positionChanged(duration()); + stateChanged(QMediaPlayer::StoppedState); + mediaStatusChanged(QMediaPlayer::EndOfMedia); +} + float QFFmpegMediaPlayer::bufferProgress() const { return 1.; @@ -112,7 +121,9 @@ void QFFmpegMediaPlayer::setMedia(const QUrl &media, QIODevice *stream) } mediaStatusChanged(QMediaPlayer::LoadingMedia); - decoder = new Decoder(this); + decoder = new Decoder; + connect(decoder, &Decoder::endOfStream, this, &QFFmpegMediaPlayer::endOfStream); + connect(decoder, &Decoder::errorOccured, this, &QFFmpegMediaPlayer::error); decoder->setMedia(media, stream); decoder->setAudioSink(m_audioOutput); decoder->setVideoSink(m_videoSink); @@ -125,6 +136,7 @@ void QFFmpegMediaPlayer::setMedia(const QUrl &media, QIODevice *stream) audioAvailableChanged(!decoder->m_streamMap[QPlatformMediaPlayer::AudioStream].isEmpty()); videoAvailableChanged(!decoder->m_streamMap[QPlatformMediaPlayer::VideoStream].isEmpty()); + QMetaObject::invokeMethod(this, "delayedLoadedStatus", Qt::QueuedConnection); } @@ -133,8 +145,10 @@ void QFFmpegMediaPlayer::play() if (!decoder) return; - if (mediaStatus() == QMediaPlayer::EndOfMedia && state() == QMediaPlayer::StoppedState) + if (mediaStatus() == QMediaPlayer::EndOfMedia && state() == QMediaPlayer::StoppedState) { decoder->seek(0); + positionChanged(0); + } decoder->play(); positionUpdateTimer.start(); stateChanged(QMediaPlayer::PlayingState); @@ -145,8 +159,10 @@ void QFFmpegMediaPlayer::pause() { if (!decoder) return; - if (mediaStatus() == QMediaPlayer::EndOfMedia && state() == QMediaPlayer::StoppedState) + if (mediaStatus() == QMediaPlayer::EndOfMedia && state() == QMediaPlayer::StoppedState) { decoder->seek(0); + positionChanged(0); + } decoder->pause(); positionUpdateTimer.stop(); stateChanged(QMediaPlayer::PausedState); @@ -159,6 +175,7 @@ void QFFmpegMediaPlayer::stop() return; decoder->stop(); positionUpdateTimer.stop(); + positionChanged(0); stateChanged(QMediaPlayer::StoppedState); mediaStatusChanged(QMediaPlayer::LoadedMedia); } diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer_p.h b/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer_p.h index e0dd94ba4..8e2753c82 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaplayer_p.h @@ -71,6 +71,11 @@ public: private slots: void updatePosition(); + void endOfStream(); + void error(int error, const QString &errorString) + { + QPlatformMediaPlayer::error(error, errorString); + } private: friend class QFFmpeg::Decoder; -- cgit v1.2.3