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 "qtimer.h" |
7 | #include "qdebug.h" |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | namespace QFFmpeg { |
12 | |
13 | static QAtomicInteger<PlaybackEngineObject::Id> PersistentId = 0; |
14 | |
15 | PlaybackEngineObject::PlaybackEngineObject() : m_id(PersistentId.fetchAndAddRelaxed(valueToAdd: 1)) { } |
16 | |
17 | PlaybackEngineObject::~PlaybackEngineObject() |
18 | { |
19 | if (!thread()->isCurrentThread()) |
20 | qWarning() << "The playback engine object is being removed in an unexpected thread"; |
21 | } |
22 | |
23 | bool PlaybackEngineObject::isPaused() const |
24 | { |
25 | return m_paused; |
26 | } |
27 | |
28 | void PlaybackEngineObject::setAtEnd(bool isAtEnd) |
29 | { |
30 | if (m_atEnd.testAndSetRelease(expectedValue: !isAtEnd, newValue: isAtEnd) && isAtEnd) |
31 | emit atEnd(); |
32 | } |
33 | |
34 | bool PlaybackEngineObject::isAtEnd() const |
35 | { |
36 | return m_atEnd; |
37 | } |
38 | |
39 | PlaybackEngineObject::Id PlaybackEngineObject::id() const |
40 | { |
41 | return m_id; |
42 | } |
43 | |
44 | void PlaybackEngineObject::setPaused(bool isPaused) |
45 | { |
46 | if (m_paused.testAndSetRelease(expectedValue: !isPaused, newValue: isPaused)) |
47 | QMetaObject::invokeMethod(object: this, function: &PlaybackEngineObject::onPauseChanged); |
48 | } |
49 | |
50 | void PlaybackEngineObject::kill() |
51 | { |
52 | m_deleting.storeRelease(newValue: true); |
53 | |
54 | disconnect(); |
55 | deleteLater(); |
56 | } |
57 | |
58 | bool PlaybackEngineObject::canDoNextStep() const |
59 | { |
60 | return !m_paused; |
61 | } |
62 | |
63 | QTimer &PlaybackEngineObject::timer() |
64 | { |
65 | if (!m_timer) { |
66 | m_timer = std::make_unique<QTimer>(); |
67 | m_timer->setTimerType(Qt::PreciseTimer); |
68 | m_timer->setSingleShot(true); |
69 | connect(sender: m_timer.get(), signal: &QTimer::timeout, context: this, slot: &PlaybackEngineObject::onTimeout); |
70 | } |
71 | |
72 | return *m_timer; |
73 | } |
74 | |
75 | void PlaybackEngineObject::onTimeout() |
76 | { |
77 | if (!m_deleting && canDoNextStep()) |
78 | doNextStep(); |
79 | } |
80 | |
81 | std::chrono::milliseconds PlaybackEngineObject::timerInterval() const |
82 | { |
83 | using namespace std::chrono_literals; |
84 | return 0ms; |
85 | } |
86 | |
87 | void PlaybackEngineObject::onPauseChanged() |
88 | { |
89 | scheduleNextStep(); |
90 | } |
91 | |
92 | void PlaybackEngineObject::scheduleNextStep(bool allowDoImmediatelly) |
93 | { |
94 | using std::chrono::milliseconds; |
95 | using namespace std::chrono_literals; |
96 | |
97 | if (!m_deleting && canDoNextStep()) { |
98 | const milliseconds interval = timerInterval(); |
99 | if (interval == 0ms && allowDoImmediatelly) { |
100 | timer().stop(); |
101 | doNextStep(); |
102 | } else { |
103 | timer().start(msec: static_cast<int>(interval.count())); |
104 | } |
105 | } else { |
106 | timer().stop(); |
107 | } |
108 | } |
109 | } // namespace QFFmpeg |
110 | |
111 | QT_END_NAMESPACE |
112 | |
113 | #include "moc_qffmpegplaybackengineobject_p.cpp" |
114 |