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> now;
102
103 if (m_stepType == StepType::None && m_nextTimePoint) {
104 if (now = SteadyClock::now(); *m_nextTimePoint <= *now) {
105 m_nextTimePoint.reset();
106 doNextStep(StepType::Immediate);
107 now.reset(); // doNextStep() may take some time, 'now' is not valid anymore
108 }
109 }
110
111 if (m_nextTimePoint) {
112 if (!now)
113 now = SteadyClock::now();
114 *m_nextTimePoint = std::max(*m_nextTimePoint, *now);
115 if (!m_timePoint || *m_nextTimePoint != std::max(*m_timePoint, *now)) {
116 timer().setInterval(*m_nextTimePoint - *now);
117 timer().start();
118 }
119 } else if (m_timePoint) {
120 timer().stop();
121 }
122
123 m_timePoint = std::exchange(m_nextTimePoint, std::nullopt);
124}
125
126void PlaybackEngineObject::doNextStep(StepType type)
127{
128 Q_ASSERT(m_stepType == StepType::None && type != StepType::None);
129 QScopedValueRollback rollback(m_stepType, type);
131}
132
134{
135 if (e->type() == FuncEventType) {
136 e->accept();
137 static_cast<FuncEvent *>(e)->invoke();
138 return true;
139 }
140
141 return QObject::event(e);
142}
143
144} // namespace QFFmpeg
145
146QT_END_NAMESPACE
147
148#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.