summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-05-09 18:04:53 +0200
committerArtem Dyomin <artem.dyomin@qt.io>2023-07-07 13:23:52 +0000
commit98d8754756e0a3d43aabdb4637254085fa716a0d (patch)
treed844ead12f1de81d1fbcd1461ae1001e3dbc71b2 /src/plugins/multimedia/ffmpeg/playbackengine/qffmpegrenderer.cpp
parent4f7cc2d18e1df909da9285198779711a58add72e (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.cpp46
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