Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qffmpegclock.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#include <qffmpegclock_p.h>
4#include <qloggingcategory.h>
5
6static Q_LOGGING_CATEGORY(qLcClock, "qt.multimedia.ffmpeg.clock")
7
9
10static bool compareClocks(const QFFmpeg::Clock *a, const QFFmpeg::Clock *b)
11{
12 if (!b)
13 return false;
14
15 if (!a)
16 return true;
17
18 return a->type() < b->type();
19}
20
22 : controller(controller)
23{
24 Q_ASSERT(controller);
25 controller->addClock(this);
26}
27
29{
30 if (controller)
31 controller->removeClock(this);
32}
33
35{
36 return controller ? controller->currentTime() : 0;
37}
38
40{
41 qCDebug(qLcClock) << "syncTo" << time << isMaster();
42}
43
45{
46 qCDebug(qLcClock) << "Clock::setPlaybackRate" << rate;
49}
50
52{
53 qCDebug(qLcClock) << "Clock::setPaused" << paused;
54 Q_UNUSED(paused)
55}
56
58{
59 if (controller)
60 return controller->timeUpdated(this, currentTime);
61 return currentTime;
62}
63
65{
66 if (!controller || controller->m_isPaused)
67 return -1;
68 const qint64 t = qRound64((displayTime - currentTime) / playbackRate());
69 return t < 0 ? 0 : t;
70}
71
73{
74 return SystemClock;
75}
76
78{
79 for (auto *p : std::as_const(m_clocks))
80 p->setController(nullptr);
81}
82
83qint64 QFFmpeg::ClockController::timeUpdated(Clock *clock, qint64 time)
84{
85 QMutexLocker l(&m_mutex);
86 if (!isMaster(clock)) {
87 // If the clock isn't the master clock, simply return the current time
88 // so we can make adjustments as needed
89 return currentTimeNoLock();
90 }
91
92 // if the clock is the master, adjust our base timing
93 m_baseTime = time;
94 m_elapsedTimer.restart();
95
96 return time;
97}
98
99void QFFmpeg::ClockController::addClock(Clock *clock)
100{
101 qCDebug(qLcClock) << "addClock" << clock;
102 Q_ASSERT(clock != nullptr);
103
104 if (m_clocks.contains(clock))
105 return;
106
107 m_clocks.append(clock);
108 m_master = std::max(m_master.loadAcquire(), clock, compareClocks);
109
110 clock->syncTo(currentTime());
111 clock->setPaused(m_isPaused);
112}
113
114void QFFmpeg::ClockController::removeClock(Clock *clock)
115{
116 qCDebug(qLcClock) << "removeClock" << clock;
117 m_clocks.removeAll(clock);
118 if (m_master == clock) {
119 // find a new master clock
120 m_master = m_clocks.empty()
121 ? nullptr
122 : *std::max_element(m_clocks.begin(), m_clocks.end(), compareClocks);
123 }
124}
125
126bool QFFmpeg::ClockController::isMaster(const Clock *clock) const
127{
128 return m_master.loadAcquire() == clock;
129}
130
131qint64 QFFmpeg::ClockController::currentTimeNoLock() const
132{
133 return m_isPaused ? m_baseTime : m_baseTime + m_elapsedTimer.elapsed() / m_playbackRate;
134}
135
137{
138 QMutexLocker l(&m_mutex);
139 return currentTimeNoLock();
140}
141
143{
144 {
145 QMutexLocker l(&m_mutex);
146 qCDebug(qLcClock) << "syncTo" << usecs;
147 m_baseTime = usecs;
148 m_seekTime = usecs;
149 m_elapsedTimer.restart();
150 }
151
152 for (auto *p : std::as_const(m_clocks))
153 p->syncTo(usecs);
154}
155
157{
158 qint64 baseTime = 0;
159 {
160 qCDebug(qLcClock) << "setPlaybackRate" << rate;
161
162 QMutexLocker l(&m_mutex);
163
164 m_baseTime = baseTime = currentTimeNoLock();
165 m_elapsedTimer.restart();
166 m_playbackRate = rate;
167 }
168
169 for (auto *p : std::as_const(m_clocks))
170 p->setPlaybackRate(rate, baseTime);
171}
172
174{
175 {
176 QMutexLocker l(&m_mutex);
177 if (m_isPaused == paused)
178 return;
179 qCDebug(qLcClock) << "setPaused" << paused;
180 m_isPaused = paused;
181 if (m_isPaused) {
182 m_baseTime = currentTimeNoLock();
183 m_seekTime = m_baseTime;
184 } else {
185 m_elapsedTimer.restart();
186 }
187 }
188
189 for (auto *p : std::as_const(m_clocks))
190 p->setPaused(paused);
191}
192
void syncTo(qint64 usecs)
void setPaused(bool paused)
virtual void syncTo(qint64 usecs)
virtual void setPaused(bool paused)
virtual Type type() const
qint64 usecsTo(qint64 currentTime, qint64 displayTime)
virtual void setPlaybackRate(float rate, qint64 currentTime)
Clock(ClockController *controller)
qint64 currentTime() const
qint64 timeUpdated(qint64 currentTime)
\inmodule QtCore
Definition qmutex.h:317
Combined button and popup list for selecting options.
std::optional< qint64 > baseTime
qint64 qRound64(qfloat16 d) noexcept
Definition qfloat16.h:284
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLenum * rate
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_UNUSED(x)
long long qint64
Definition qtypes.h:55
static double currentTime()
QObject::connect nullptr