diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-05-09 18:04:53 +0200 |
---|---|---|
committer | Artem Dyomin <artem.dyomin@qt.io> | 2023-07-07 13:23:52 +0000 |
commit | 98d8754756e0a3d43aabdb4637254085fa716a0d (patch) | |
tree | d844ead12f1de81d1fbcd1461ae1001e3dbc71b2 /src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp | |
parent | 4f7cc2d18e1df909da9285198779711a58add72e (diff) |
Fix audioplayback of large frames and improve synchronization
In some cases audioframes are larger than buffer size,
we should be able to handle them.
As a result, the audio playback and audio synchronization
have been improved.
Task-number: QTBUG-113211
Pick-to: 6.5 6.6
Change-Id: I6cd2650f9b66e924e152919a0974a9687b2d3bf4
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp')
-rw-r--r-- | src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp index 735f0b12e..123dee5a4 100644 --- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp +++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp @@ -50,10 +50,13 @@ void Renderer::doForceStep() QMetaObject::invokeMethod(this, [this]() { // maybe set m_forceStepMaxPos - if (isAtEnd()) + if (isAtEnd()) { setForceStepDone(); - else + } + else { + m_explicitNextFrameTime = Clock::now(); scheduleNextStep(); + } }); } @@ -69,8 +72,6 @@ void Renderer::onFinalFrameReceived() void Renderer::render(Frame frame) { - using namespace std::chrono; - const auto isFrameOutdated = frame.isValid() && frame.absoluteEnd() < m_seekPos; if (isFrameOutdated) { @@ -104,10 +105,15 @@ float Renderer::playbackRate() const int Renderer::timerInterval() const { - if (auto frame = m_frames.front(); frame.isValid() && !m_isStepForced) { + auto frame = !m_frames.empty() ? m_frames.front() : Frame(); + if (frame.isValid()) { using namespace std::chrono; - const auto delay = - m_timeController.timeFromPosition(frame.absolutePts()) - steady_clock::now(); + + const auto nextTime = m_explicitNextFrameTime + ? *m_explicitNextFrameTime + : m_timeController.timeFromPosition(frame.absolutePts()); + + const auto delay = nextTime - Clock::now(); return std::max(0, static_cast<int>(duration_cast<milliseconds>(delay).count())); } @@ -119,6 +125,7 @@ bool Renderer::setForceStepDone() if (!m_isStepForced.exchange(false)) return false; + m_explicitNextFrameTime.reset(); emit forceStepDone(); return true; } @@ -135,15 +142,9 @@ void Renderer::doNextStep() } const auto result = renderInternal(frame); - const bool done = result.timeLeft.count() <= 0; - if (result.timeLeft.count() && frame.isValid()) { - const auto now = std::chrono::steady_clock::now(); - m_timeController.sync(now + result.timeLeft, frame.absolutePts()); - emit synchronized(now + result.timeLeft, frame.absolutePts()); - } - - if (done) { + if (result.done) { + m_explicitNextFrameTime.reset(); m_frames.dequeue(); if (frame.isValid()) { @@ -158,9 +159,11 @@ void Renderer::doNextStep() emit frameProcessed(frame); } + } else { + m_explicitNextFrameTime = Clock::now() + result.recheckInterval; } - setAtEnd(done && !frame.isValid()); + setAtEnd(result.done && !frame.isValid()); scheduleNextStep(false); } @@ -168,8 +171,17 @@ void Renderer::doNextStep() std::chrono::microseconds Renderer::frameDelay(const Frame &frame) const { return std::chrono::duration_cast<std::chrono::microseconds>( - TimeController::Clock::now() - m_timeController.timeFromPosition(frame.absolutePts())); + Clock::now() - m_timeController.timeFromPosition(frame.absolutePts())); } + +void Renderer::changeRendererTime(std::chrono::microseconds offset) +{ + const auto now = Clock::now(); + const auto pos = m_timeController.positionFromTime(now); + m_timeController.sync(now + offset, pos); + emit synchronized(now + offset, pos); +} + } // namespace QFFmpeg QT_END_NAMESPACE |