Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qffmpegtimecontroller.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
4#include "playbackengine/qffmpegtimecontroller_p.h"
5
7
8namespace QFFmpeg {
9
11{
12 sync();
13}
14
16{
17 return m_playbackRate;
18}
19
21{
22 if (playbackRate == m_playbackRate)
23 return;
24
25 Q_ASSERT(playbackRate > 0.f);
26
27 scrollTimeTillNow();
28 m_playbackRate = playbackRate;
29
30 if (m_softSyncData)
31 m_softSyncData = makeSoftSyncData(m_timePoint, m_position, m_softSyncData->dstTimePoint);
32}
33
34void TimeController::sync(TrackPosition trackPos)
35{
36 sync(SteadyClock::now(), trackPos);
37}
38
39void TimeController::sync(TimePoint tp, TrackPosition pos)
40{
41 m_softSyncData.reset();
42 m_position = pos;
43 m_timePoint = tp;
44}
45
46void TimeController::syncSoft(TimePoint tp, TrackPosition pos, SteadyClock::duration fixingTime)
47{
48 const auto srcTime = SteadyClock::now();
49 const auto srcPos = positionFromTime(srcTime, true);
50 const auto dstTime = srcTime + fixingTime;
51
52 m_position = pos;
53 m_timePoint = tp;
54
55 m_softSyncData = makeSoftSyncData(srcTime, srcPos, dstTime);
56}
57
58TrackPosition TimeController::currentPosition(SteadyClock::duration offset) const
59{
60 return positionFromTime(SteadyClock::now() + offset);
61}
63{
64 m_started = true;
65 updateActive();
66}
67
69{
70 m_started = false;
71 m_paused = true;
72 updateActive();
73}
74
75void TimeController::setPaused(bool paused)
76{
77 m_paused = paused;
78 updateActive();
79}
80
81void TimeController::updateActive()
82{
83 const bool active = !m_paused && m_started;
84 if (m_active == active)
85 return;
86
87 scrollTimeTillNow();
88
89 m_active = active;
90}
91
92TrackPosition TimeController::positionFromTime(TimePoint tp, bool ignoreInactive) const
93{
94 tp = !m_active && !ignoreInactive ? m_timePoint : tp;
95
96 if (m_softSyncData && tp < m_softSyncData->dstTimePoint) {
97 const PlaybackRate rate =
98 tp > m_softSyncData->srcTimePoint ? m_softSyncData->internalRate : m_playbackRate;
99
100 return m_softSyncData->srcPosition
101 + toTrackDuration(tp - m_softSyncData->srcTimePoint, rate);
102 }
103
104 return positionFromTimeInternal(tp);
105}
106
108 bool ignoreInactive) const
109{
110 auto position = !m_active && !ignoreInactive ? m_position : TrackPosition(pos);
111
112 if (m_softSyncData && position < m_softSyncData->dstPosition) {
113 const auto rate = position > m_softSyncData->srcPosition ? m_softSyncData->internalRate
114 : m_playbackRate;
115 return m_softSyncData->srcTimePoint
116 + toClockDuration(position - m_softSyncData->srcPosition, rate);
117 }
118
119 return timeFromPositionInternal(position);
120}
121
122TimeController::SoftSyncData TimeController::makeSoftSyncData(const TimePoint &srcTp,
123 const TrackPosition &srcPos,
124 const TimePoint &dstTp) const
125{
126 SoftSyncData result;
127 result.srcTimePoint = srcTp;
128 result.srcPosition = srcPos;
129 result.dstTimePoint = dstTp;
130 result.srcPosOffest = srcPos - positionFromTimeInternal(srcTp);
131 result.dstPosition = positionFromTimeInternal(dstTp);
132 result.internalRate =
133 static_cast<PlaybackRate>(toClockDuration(result.dstPosition - srcPos).count())
134 / (dstTp - srcTp).count();
135
136 return result;
137}
138
139TrackPosition TimeController::positionFromTimeInternal(const TimePoint &tp) const
140{
141 return m_position + toTrackDuration(tp - m_timePoint, m_playbackRate);
142}
143
144TimeController::TimePoint TimeController::timeFromPositionInternal(const TrackPosition &pos) const
145{
146 return m_timePoint + toClockDuration(pos - m_position, m_playbackRate);
147}
148
149void TimeController::scrollTimeTillNow()
150{
151 const auto now = SteadyClock::now();
152 if (m_active) {
153 m_position = positionFromTimeInternal(now);
154
155 // let's forget outdated syncronizations
156 if (m_softSyncData && m_softSyncData->dstTimePoint <= now)
157 m_softSyncData.reset();
158 } else if (m_softSyncData) {
159 m_softSyncData->dstTimePoint += now - m_timePoint;
160 m_softSyncData->srcTimePoint += now - m_timePoint;
161 }
162
163 m_timePoint = now;
164}
165
166SteadyClock::duration TimeController::toClockDuration(TrackDuration trackDuration, PlaybackRate rate)
167{
168 return std::chrono::duration_cast<SteadyClock::duration>(
169 std::chrono::microseconds(trackDuration.get()) / rate);
170}
171
172TrackDuration TimeController::toTrackDuration(SteadyClock::duration clockDuration, PlaybackRate rate)
173{
174 return TrackDuration(
175 std::chrono::duration_cast<std::chrono::microseconds>(clockDuration * rate).count());
176}
177
178} // namespace QFFmpeg
179
180QT_END_NAMESPACE
void syncSoft(TimePoint tp, TrackPosition pos, SteadyClock::duration fixingTime=std::chrono::seconds(4))
PlaybackRate playbackRate() const
TrackPosition currentPosition(SteadyClock::duration offset=SteadyClock::duration{ 0 }) const
TimePoint timeFromPosition(TrackPosition pos, bool ignoreInactive=false) const
TrackPosition positionFromTime(TimePoint tp, bool ignoreInactive=false) const
void sync(TimePoint tp, TrackPosition pos)
void setPlaybackRate(PlaybackRate playbackRate)
void sync(TrackPosition trackPos=TrackPosition(0))
QT_MANGLE_NAMESPACE(QMacScreenCaptureStreamDelegate) QMacScreenCaptureStreamDelegate
Combined button and popup list for selecting options.