diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-07-25 12:49:25 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-08-10 17:24:35 +0000 |
commit | 65d96c828b7d08bbc011cb1b466edc21cc331b31 (patch) | |
tree | c0eb0785b20bf9a24a116323a12d6e1f28316e02 | |
parent | c52c908d94ac84a90f2d3c82564d3a7b2550b830 (diff) |
Playback engine atomic variables cleanup
* use acquire-release memory order instead of default mem-seq.
The strict sequeintial order is not needed if not having
special sync requirements; the order might be a bottle-neck
if widely used in many threads.
In the future, it might be investigated and optimized
with relaxed operations in some cases.
* use QAtomic instead of std::atomic, since QAtomic has
explicit convenient methods and std::atomic sets
the mem-seq order by default.
Change-Id: Iabd9c1bc072db491e0eba7eacaf8f4ea8343cee4
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
(cherry picked from commit d64c490eb977258fd30e7a78cfed1ad6d86d3f3f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
6 files changed, 24 insertions, 25 deletions
diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer.cpp b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer.cpp index 696460c00..3c5ea8e6b 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer.cpp +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer.cpp @@ -26,15 +26,14 @@ static qint64 streamTimeToUs(const AVStream *stream, qint64 time) Demuxer::Demuxer(AVFormatContext *context, const PositionWithOffset &posWithOffset, const StreamIndexes &streamIndexes, int loops) - : m_context(context), m_posWithOffset(posWithOffset) + : m_context(context), m_posWithOffset(posWithOffset), m_loops(loops) { qCDebug(qLcDemuxer) << "Create demuxer." << "pos:" << posWithOffset.pos << "loop offset:" << posWithOffset.offset.pos << "loop index:" << posWithOffset.offset.index << "loops:" << loops; - m_loops = loops; Q_ASSERT(m_context); - Q_ASSERT(m_loops < 0 || m_posWithOffset.offset.index < m_loops); + Q_ASSERT(loops < 0 || m_posWithOffset.offset.index < loops); for (auto i = 0; i < QPlatformMediaPlayer::NTrackTypes; ++i) { if (streamIndexes[i] >= 0) { @@ -53,7 +52,8 @@ void Demuxer::doNextStep() if (av_read_frame(m_context, packet.avPacket()) < 0) { ++m_posWithOffset.offset.index; - if (m_loops >= 0 && m_posWithOffset.offset.index >= m_loops) { + const auto loops = m_loops.loadAcquire(); + if (loops >= 0 && m_posWithOffset.offset.index >= loops) { qCDebug(qLcDemuxer) << "finish demuxing"; setAtEnd(true); } else { @@ -163,7 +163,7 @@ Demuxer::RequestingSignal Demuxer::signalByTrackType(QPlatformMediaPlayer::Track void Demuxer::setLoops(int loopsCount) { qCDebug(qLcDemuxer) << "setLoops to demuxer" << loopsCount; - m_loops = loopsCount; + m_loops.storeRelease(loopsCount); } } // namespace QFFmpeg diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer_p.h b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer_p.h index 290626af2..9ab293c55 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer_p.h +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegdemuxer_p.h @@ -65,7 +65,7 @@ private: std::unordered_map<int, StreamData> m_streams; PositionWithOffset m_posWithOffset; qint64 m_endPts = 0; - std::atomic<int> m_loops = QMediaPlayer::Once; + QAtomicInt m_loops = QMediaPlayer::Once; }; } // namespace QFFmpeg diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject.cpp b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject.cpp index f22799c70..2d23802de 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject.cpp +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject.cpp @@ -10,9 +10,9 @@ QT_BEGIN_NAMESPACE namespace QFFmpeg { -static std::atomic<PlaybackEngineObject::Id> PersistentId = 0; +static QAtomicInteger<PlaybackEngineObject::Id> PersistentId = 0; -PlaybackEngineObject::PlaybackEngineObject() : m_id(++PersistentId) { } +PlaybackEngineObject::PlaybackEngineObject() : m_id(PersistentId.fetchAndAddRelaxed(1)) { } PlaybackEngineObject::~PlaybackEngineObject() { @@ -27,7 +27,7 @@ bool PlaybackEngineObject::isPaused() const void PlaybackEngineObject::setAtEnd(bool isAtEnd) { - if (m_atEnd.exchange(isAtEnd) != isAtEnd) + if (m_atEnd.testAndSetRelease(!isAtEnd, isAtEnd) && isAtEnd) emit atEnd(); } @@ -43,13 +43,13 @@ PlaybackEngineObject::Id PlaybackEngineObject::id() const void PlaybackEngineObject::setPaused(bool isPaused) { - if (m_paused.exchange(isPaused) != isPaused) + if (m_paused.testAndSetRelease(!isPaused, isPaused)) QMetaObject::invokeMethod(this, &PlaybackEngineObject::onPauseChanged); } void PlaybackEngineObject::kill() { - m_deleting = true; + m_deleting.storeRelease(true); disconnect(); deleteLater(); diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject_p.h b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject_p.h index 409d18c43..02943a55b 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject_p.h +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegplaybackengineobject_p.h @@ -16,8 +16,7 @@ #include "playbackengine/qffmpegplaybackenginedefs_p.h" #include "qthread.h" - -#include <atomic> +#include "qatomic.h" QT_BEGIN_NAMESPACE @@ -73,9 +72,9 @@ private slots: private: std::unique_ptr<QTimer> m_timer; - std::atomic_bool m_paused = true; - std::atomic_bool m_atEnd = false; - std::atomic_bool m_deleting = false; + QAtomicInteger<bool> m_paused = true; + QAtomicInteger<bool> m_atEnd = false; + QAtomicInteger<bool> m_deleting = false; const Id m_id; }; } // namespace QFFmpeg diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp index 56bfd9092..8ef298105 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp @@ -46,7 +46,7 @@ void Renderer::setPlaybackRate(float rate) void Renderer::doForceStep() { - if (!m_isStepForced.exchange(true)) + if (m_isStepForced.testAndSetOrdered(false, true)) QMetaObject::invokeMethod(this, [this]() { // maybe set m_forceStepMaxPos @@ -72,11 +72,11 @@ void Renderer::onFinalFrameReceived() void Renderer::render(Frame frame) { - const auto isFrameOutdated = frame.isValid() && frame.absoluteEnd() < m_seekPos; + const auto isFrameOutdated = frame.isValid() && frame.absoluteEnd() < seekPosition(); if (isFrameOutdated) { qCDebug(qLcRenderer) << "frame outdated! absEnd:" << frame.absoluteEnd() << "absPts" - << frame.absolutePts() << "seekPos:" << m_seekPos; + << frame.absolutePts() << "seekPos:" << seekPosition(); emit frameProcessed(frame); return; } @@ -122,7 +122,7 @@ int Renderer::timerInterval() const bool Renderer::setForceStepDone() { - if (!m_isStepForced.exchange(false)) + if (!m_isStepForced.testAndSetOrdered(true, false)) return false; m_explicitNextFrameTime.reset(); @@ -148,8 +148,8 @@ void Renderer::doNextStep() m_frames.dequeue(); if (frame.isValid()) { - m_lastPosition = std::max(frame.absolutePts(), m_lastPosition.load()); - m_seekPos = frame.absoluteEnd(); + m_lastPosition.storeRelease(std::max(frame.absolutePts(), lastPosition())); + m_seekPos.storeRelaxed(frame.absoluteEnd()); const auto loopIndex = frame.loopOffset().index; if (m_loopIndex < loopIndex) { diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer_p.h b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer_p.h index e14076624..9b5139ad9 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer_p.h +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer_p.h @@ -102,12 +102,12 @@ private: private: TimeController m_timeController; - std::atomic<qint64> m_lastPosition = 0; - std::atomic<qint64> m_seekPos = 0; + QAtomicInteger<qint64> m_lastPosition = 0; + QAtomicInteger<qint64> m_seekPos = 0; int m_loopIndex = 0; QQueue<Frame> m_frames; - std::atomic_bool m_isStepForced = false; + QAtomicInteger<bool> m_isStepForced = false; std::optional<TimePoint> m_explicitNextFrameTime; }; |