79 if (frame.isValid() && !checkSessionID(frame.sourceID().sessionID)) {
80 qCDebug(qLcRenderer) <<
"Frame session outdated. Source id:" << frame.sourceID() <<
"current id:" << id();
85 const bool frameOutdated = frame.isValid() && frame.absoluteEnd() < seekPosition();
88 qCDebug(qLcRenderer) <<
"frame outdated! absEnd:" << frame.absoluteEnd().get() <<
"absPts"
89 << frame.absolutePts().get() <<
"seekPos:" << seekPosition().get();
91 emit frameProcessed(std::move(frame));
95 m_frames.enqueue(std::move(frame));
97 if (m_frames.size() == 1)
127 using namespace std::chrono_literals;
129 if (m_frames.empty())
130 return PlaybackEngineObject::nextTimePoint();
132 if (m_explicitNextFrameTime)
133 return *m_explicitNextFrameTime;
135 if (m_frames.front().isValid())
136 return m_timeController.timeFromPosition(m_frames.front().absolutePts());
138 if (m_lastFrameEnd > TrackPosition(0))
139 return m_timeController.timeFromPosition(m_lastFrameEnd);
141 return PlaybackEngineObject::nextTimePoint();
156 Frame frame = m_frames.front();
165 const auto result = renderInternal(frame);
166 const bool frameIsValid = frame.isValid();
169 m_explicitNextFrameTime.reset();
173 m_lastPosition.storeRelease(std::max(frame.absolutePts(), lastPosition()).get());
176 m_lastFrameEnd = frame.absoluteEnd();
177 m_seekPos.storeRelaxed(m_lastFrameEnd.get());
179 const auto loopIndex = frame.loopOffset().loopIndex;
180 if (m_loopIndex < loopIndex) {
181 m_loopIndex = loopIndex;
182 emit loopChanged(id(), frame.loopOffset().loopStartTimeUs, m_loopIndex);
185 emit frameProcessed(std::move(frame));
187 m_lastPosition.storeRelease(std::max(m_lastFrameEnd, lastPosition()).get());
190 m_explicitNextFrameTime = SteadyClock::now() + result.recheckInterval;
193 setAtEnd(result.done && !frameIsValid);
206 const auto now = SteadyClock::now();
207 const auto pos = m_timeController.positionFromTime(now);
208 m_timeController.sync(now + offset, pos);
209 emit synchronized(id(), now + offset, pos);