Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qffmpegrenderer.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
"qffmpegrenderer_p.h"
5
6
#
include
<
QtCore
/
qloggingcategory
.
h
>
7
8
QT_BEGIN_NAMESPACE
9
10
namespace
QFFmpeg
{
11
12
Q_STATIC_LOGGING_CATEGORY
(
qLcRenderer
,
"qt.multimedia.ffmpeg.renderer"
);
13
14
Renderer
::
Renderer
(
const
PlaybackEngineObjectID &id,
const
TimeController &tc)
15
:
PlaybackEngineObject
(
id
),
m_sessionCtx
{
tc
}
16
{
17
}
18
19
TrackPosition
Renderer
::
seekPosition
()
const
20
{
21
return
TrackPosition(m_sessionCtx.seekPos);
22
}
23
24
TrackPosition
Renderer
::
lastPosition
()
const
25
{
26
return
TrackPosition(m_sessionCtx.lastPosition);
27
}
28
29
void
Renderer
::
setPlaybackRate
(
float
rate)
30
{
31
invokePriorityMethod([
this
, rate]() {
32
m_sessionCtx.timeController.setPlaybackRate(rate);
33
onPlaybackRateChanged
(
)
;
34
scheduleNextStep();
35
});
36
}
37
38
void
Renderer
::
doForceStep
()
39
{
40
if
(m_isStepForced.testAndSetOrdered(
false
,
true
))
41
invokePriorityMethod([
this
]() {
42
// maybe set m_forceStepMaxPos
43
44
if
(isAtEnd()) {
45
setForceStepDone
(
)
;
46
}
47
else
{
48
m_sessionCtx.explicitNextFrameTime = SteadyClock::now();
49
scheduleNextStep();
50
}
51
});
52
}
53
54
bool
Renderer
::
isStepForced
()
const
55
{
56
return
m_isStepForced;
57
}
58
59
void
Renderer
::
setTimeController
(
const
TimeController &tc)
60
{
61
Q_ASSERT(tc.isStarted());
62
invokePriorityMethod([
this
, tc]() {
63
m_sessionCtx.timeController = tc;
64
scheduleNextStep();
65
});
66
}
67
68
void
Renderer
::
seek
(quint64 sessionId,
const
TimeController &tc,
const
LoopOffset &offset)
69
{
70
updateSession(sessionId, [
this
, tc, offset]() {
71
m_sessionCtx = { tc, offset.loopIndex };
72
// don't clean m_isStepForced, otherwise a single frame might not be forced on pause
73
74
seekInternal
(
)
;
75
});
76
}
77
78
void
Renderer
::onFinalFrameReceived(PlaybackEngineObjectID sourceID)
79
{
80
if
(checkSessionID(sourceID.sessionID))
81
render({});
82
}
83
84
void
Renderer
::
render
(Frame frame)
85
{
86
if
(frame.isValid() && !checkSessionID(frame.sourceID().sessionID)) {
87
qCDebug(qLcRenderer) <<
"Frame session outdated. Source id:"
<< frame.sourceID() <<
"current id:"
<< id();
88
// else don't need to report
89
return
;
90
}
91
92
const
bool
frameOutdated = frame.isValid() && frame.absoluteEnd() < seekPosition();
93
94
if
(frameOutdated) {
95
qCDebug(qLcRenderer) <<
"frame outdated! absEnd:"
<< frame.absoluteEnd().get() <<
"absPts"
96
<< frame.absolutePts().get() <<
"seekPos:"
<< seekPosition().get();
97
98
Q_EMIT frameProcessed(std::move(frame));
99
return
;
100
}
101
102
m_sessionCtx.frames.enqueue(std::move(frame));
103
104
if
(m_sessionCtx.frames.size() == 1)
105
scheduleNextStep();
106
}
107
108
void
Renderer
::
onPauseChanged
()
109
{
110
m_sessionCtx.timeController.setPaused(isPaused());
111
PlaybackEngineObject::onPauseChanged();
112
}
113
114
bool
Renderer
::
canDoNextStep
()
const
115
{
116
if
(m_sessionCtx.frames.empty())
117
return
false
;
118
// do the step even if the TC is not started;
119
// may be changed if the case is found.
120
if
(m_isStepForced)
121
return
true
;
122
if
(!m_sessionCtx.timeController.isStarted())
123
return
false
;
124
return
PlaybackEngineObject::canDoNextStep();
125
}
126
127
float
Renderer
::
playbackRate
()
const
128
{
129
return
m_sessionCtx.timeController.playbackRate();
130
}
131
132
Renderer
::
TimePoint
Renderer
::
nextTimePoint
()
const
133
{
134
using
namespace
std
::chrono_literals;
135
136
if
(m_sessionCtx.frames.empty())
137
return
PlaybackEngineObject::nextTimePoint();
138
139
if
(m_sessionCtx.explicitNextFrameTime)
140
return
*m_sessionCtx.explicitNextFrameTime;
141
142
if
(m_sessionCtx.frames.front().isValid())
143
return
m_sessionCtx.timeController.timeFromPosition(
144
m_sessionCtx.frames.front().absolutePts());
145
146
if
(m_sessionCtx.lastFrameEnd > TrackPosition(0))
147
return
m_sessionCtx.timeController.timeFromPosition(m_sessionCtx.lastFrameEnd);
148
149
return
PlaybackEngineObject::nextTimePoint();
150
}
151
152
bool
Renderer
::
setForceStepDone
()
153
{
154
if
(!m_isStepForced.testAndSetOrdered(
true
,
false
))
155
return
false
;
156
157
m_sessionCtx.explicitNextFrameTime.reset();
158
Q_EMIT forceStepDone();
159
return
true
;
160
}
161
162
void
Renderer
::
doNextStep
()
163
{
164
Frame frame = m_sessionCtx.frames.front();
165
166
if
(
setForceStepDone
(
)
) {
167
// if (frame.isValid() && frame.pts() > m_forceStepMaxPos) {
168
// scheduleNextStep();
169
// return;
170
// }
171
}
172
173
const
auto
result = renderInternal(frame);
174
const
bool
frameIsValid = frame.isValid();
175
176
if
(result.done) {
177
m_sessionCtx.explicitNextFrameTime.reset();
178
m_sessionCtx.frames.dequeue();
179
180
if
(frameIsValid) {
181
m_sessionCtx.lastPosition.storeRelease(
182
std::max(frame.absolutePts(), lastPosition()).get());
183
184
// TODO: get rid of m_lastFrameEnd or m_seekPos
185
m_sessionCtx.lastFrameEnd = frame.absoluteEnd();
186
m_sessionCtx.seekPos.storeRelaxed(m_sessionCtx.lastFrameEnd.get());
187
188
const
auto
loopIndex = frame.loopOffset().loopIndex;
189
if
(m_sessionCtx.loopIndex < loopIndex) {
190
m_sessionCtx.loopIndex = loopIndex;
191
Q_EMIT loopChanged(id(), frame.loopOffset().loopStartTimeUs, m_sessionCtx.loopIndex);
192
}
193
194
Q_EMIT frameProcessed(std::move(frame));
195
}
else
{
196
m_sessionCtx.lastPosition.storeRelease(
197
std::max(m_sessionCtx.lastFrameEnd, lastPosition()).get());
198
}
199
}
else
{
200
m_sessionCtx.explicitNextFrameTime = SteadyClock::now() + result.recheckInterval;
201
}
202
203
setAtEnd(result.done && !frameIsValid);
204
205
scheduleNextStep();
206
}
207
208
std
::chrono::microseconds
Renderer
::
frameDelay
(
const
Frame &frame, TimePoint timePoint)
const
209
{
210
return
std
::chrono::duration_cast<
std
::chrono::microseconds>(
211
timePoint - m_sessionCtx.timeController.timeFromPosition(frame.absolutePts()));
212
}
213
214
void
Renderer
::
changeRendererTime
(
std
::chrono::microseconds offset)
215
{
216
const
auto
now = SteadyClock::now();
217
const
auto
pos = m_sessionCtx.timeController.positionFromTime(now);
218
m_sessionCtx.timeController.sync(now + offset, pos);
219
Q_EMIT synchronized(id(), now + offset, pos);
220
}
221
222
}
// namespace QFFmpeg
223
224
QT_END_NAMESPACE
225
226
#
include
"moc_qffmpegrenderer_p.cpp"
QFFmpeg::Renderer
Definition
qffmpegrenderer_p.h:31
QFFmpeg::Renderer::render
void render(Frame)
Definition
qffmpegrenderer.cpp:84
QFFmpeg::Renderer::onPauseChanged
void onPauseChanged() override
Definition
qffmpegrenderer.cpp:108
QFFmpeg::Renderer::frameDelay
std::chrono::microseconds frameDelay(const Frame &frame, TimePoint timePoint=SteadyClock::now()) const
Definition
qffmpegrenderer.cpp:208
QFFmpeg::Renderer::Renderer
Renderer(const PlaybackEngineObjectID &id, const TimeController &tc)
Definition
qffmpegrenderer.cpp:14
QFFmpeg::Renderer::doNextStep
void doNextStep() override
Definition
qffmpegrenderer.cpp:162
QFFmpeg::Renderer::setForceStepDone
bool setForceStepDone()
Definition
qffmpegrenderer.cpp:152
QFFmpeg::Renderer::canDoNextStep
bool canDoNextStep() const override
Definition
qffmpegrenderer.cpp:114
QFFmpeg::Renderer::doForceStep
void doForceStep()
Definition
qffmpegrenderer.cpp:38
QFFmpeg::Renderer::setTimeController
void setTimeController(const TimeController &tc)
Definition
qffmpegrenderer.cpp:59
QFFmpeg::Renderer::setPlaybackRate
void setPlaybackRate(float rate)
Definition
qffmpegrenderer.cpp:29
QFFmpeg::Renderer::seek
void seek(quint64 sessionId, const TimeController &tc, const LoopOffset &offset)
Definition
qffmpegrenderer.cpp:68
QFFmpeg::Renderer::playbackRate
float playbackRate() const
Definition
qffmpegrenderer.cpp:127
QFFmpeg::Renderer::nextTimePoint
TimePoint nextTimePoint() const override
Definition
qffmpegrenderer.cpp:132
QFFmpeg::Renderer::seekInternal
virtual void seekInternal()
Definition
qffmpegrenderer_p.h:76
QFFmpeg::Renderer::lastPosition
TrackPosition lastPosition() const
Definition
qffmpegrenderer.cpp:24
QFFmpeg::Renderer::onPlaybackRateChanged
virtual void onPlaybackRateChanged()
Definition
qffmpegrenderer_p.h:78
QFFmpeg::Renderer::changeRendererTime
void changeRendererTime(std::chrono::microseconds offset)
Definition
qffmpegrenderer.cpp:214
QFFmpeg::Renderer::isStepForced
bool isStepForced() const
Definition
qffmpegrenderer.cpp:54
QFFmpeg::Renderer::seekPosition
TrackPosition seekPosition() const
Definition
qffmpegrenderer.cpp:19
QFFmpeg
Definition
qandroidcacertificates.cpp:26
QFFmpeg::Q_STATIC_LOGGING_CATEGORY
Q_STATIC_LOGGING_CATEGORY(qLCAndroidCaCertificates, "qt.multimedia.ffmpeg.android.caCertificates")
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtmultimedia
src
plugins
multimedia
ffmpeg
playbackengine
qffmpegrenderer.cpp
Generated on
for Qt by
1.18.0