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
qffmpegplaybackengineobject.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/qffmpegplaybackengineobject_p.h"
5
6#include "QtCore/qchronotimer.h"
7#include "QtCore/qdebug.h"
8#include "QtCore/qscopedvaluerollback.h"
9
11
12namespace QFFmpeg {
13
14PlaybackEngineObject::PlaybackEngineObject(const PlaybackEngineObjectID &id) : m_id{ id } { }
15
17{
18 if (!thread()->isCurrentThread())
19 qWarning() << "The playback engine object is being removed in an unexpected thread";
20}
21
23{
24 return m_paused;
25}
26
27void PlaybackEngineObject::setAtEnd(bool isAtEnd)
28{
29 if (m_atEnd.testAndSetRelease(!isAtEnd, isAtEnd) && isAtEnd)
30 emit atEnd(id());
31}
32
34{
35 return m_atEnd;
36}
37
38void PlaybackEngineObject::setPaused(bool isPaused)
39{
40 if (m_paused.testAndSetRelease(!isPaused, isPaused))
41 invokePriorityMethod([this]() { onPauseChanged(); });
42}
43
45{
46 m_invalidateCounter.fetch_add(1, std::memory_order_relaxed);
47
48 disconnect();
49 deleteLater();
50}
51
53{
54 return !m_paused;
55}
56
58{
59 if (!m_timer) {
60 m_timer = std::make_unique<QChronoTimer>();
61 m_timer->setTimerType(Qt::PreciseTimer);
62 m_timer->setSingleShot(true);
63 connect(m_timer.get(), &QChronoTimer::timeout, this, &PlaybackEngineObject::onTimeout);
64 }
65
66 return *m_timer;
67}
68
69void PlaybackEngineObject::onTimeout()
70{
71 Q_ASSERT(m_timePoint && !m_nextTimePoint && m_stepType == StepType::None);
72
73 m_timePoint.reset();
74 if (isValid() && canDoNextStep())
75 doNextStep(StepType::Timeout);
76}
77
79{
80 return TimePoint::min();
81}
82
87
89{
90 using std::chrono::milliseconds;
91 using namespace std::chrono_literals;
92
93 if (isValid() && canDoNextStep())
94 m_nextTimePoint = nextTimePoint();
95 else
96 m_nextTimePoint.reset();
97
98 if (m_stepType == StepType::Immediate)
99 return;
100
101 std::optional<TimePoint> nowCached;
102 auto now = [&nowCached, this]() {
103 Q_ASSERT(m_nextTimePoint);
104
105 if (!nowCached) {
106 Q_ASSERT(m_nextTimePoint);
107 if (*m_nextTimePoint == TimePoint::min())
108 // 2 optimizations: reduce invoking SteadyClock::now() and timer's restarts
109 nowCached = TimePoint::min();
110 else
111 nowCached = SteadyClock::now();
112 }
113
114 return *nowCached;
115 };
116
117 if (m_stepType == StepType::None && m_nextTimePoint) {
118 if (*m_nextTimePoint <= now()) {
119 m_nextTimePoint.reset();
120 doNextStep(StepType::Immediate);
121 nowCached.reset(); // doNextStep() may take some time, 'now' is not valid anymore
122 }
123 }
124
125 if (m_nextTimePoint) {
126 *m_nextTimePoint = std::max(*m_nextTimePoint, now());
127 if (!m_timePoint || *m_nextTimePoint != std::max(*m_timePoint, now())) {
128 timer().setInterval(*m_nextTimePoint - now());
129 timer().start();
130 }
131 } else if (m_timePoint) {
132 timer().stop();
133 }
134
135 m_timePoint = std::exchange(m_nextTimePoint, std::nullopt);
136}
137
138void PlaybackEngineObject::doNextStep(StepType type)
139{
140 Q_ASSERT(m_stepType == StepType::None && type != StepType::None);
141 QScopedValueRollback rollback(m_stepType, type);
143}
144
146{
147 if (e->type() == FuncEventType) {
148 e->accept();
149 static_cast<FuncEvent *>(e)->invoke();
150 return true;
151 }
152
153 return QObject::event(e);
154}
155
156} // namespace QFFmpeg
157
158QT_END_NAMESPACE
159
160#include "moc_qffmpegplaybackengineobject_p.cpp"
PlaybackEngineObject(const PlaybackEngineObjectID &id)
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
std::chrono::steady_clock::time_point TimePoint
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType
Combined button and popup list for selecting options.