112 rate = DefaultScreenCaptureFrameRate;
115 if (*rate < MinScreenCaptureFrameRate)
116 rate = MinScreenCaptureFrameRate;
119 Q_ASSERT(thread()->isCurrentThread());
120 Q_ASSERT(!isGrabbingContextInitialized());
125 m_activeRate = *rate;
126 qCDebug(qLcScreenCaptureGrabber) <<
"Screen capture rate has been changed:" << *rate;
155 const QString &description)
157 std::optional<QPlatformSurfaceCapture::Error> prevError;
159 std::lock_guard locker{ m_mutex };
160 prevError = std::exchange(m_prevError, error);
163 if (error != QPlatformSurfaceCapture::Error::NoError
164 || prevError != QPlatformSurfaceCapture::Error::NoError) {
165 Q_EMIT errorUpdated(error, description);
168 updateTimerInterval();
173 using namespace std::chrono;
175 std::lock_guard locker{ m_mutex };
179 const qreal rate = m_prevError && *m_prevError != QPlatformSurfaceCapture::Error::NoError
180 ? MinScreenCaptureFrameRate
182 const nanoseconds interval = round<nanoseconds>(nanoseconds(1s) / rate);
184 if (m_timerInterval == interval)
187 QChronoTimer *timer = &m_context->timer;
188 if (timer->thread()->isCurrentThread()) {
189 timer->setInterval(interval);
190 m_timerInterval = interval;
192 const quint64 generation = m_contextGeneration;
193 QMetaObject::invokeMethod(timer, [
this, interval, generation] {
194 setTimerInterval(interval, generation);
195 }, Qt::QueuedConnection);
201 std::lock_guard locker{ m_mutex };
202 if (!m_context || generation != m_contextGeneration || m_timerInterval == interval)
205 m_context->timer.setInterval(interval);
206 m_timerInterval = interval;
211 Q_ASSERT(!isGrabbingContextInitialized());
212 qCDebug(qLcScreenCaptureGrabber) <<
"screen capture started";
215 std::lock_guard locker{ m_mutex };
216 m_context = std::make_unique<GrabbingContext>();
217 ++m_contextGeneration;
218 m_timerInterval = std::chrono::nanoseconds{ 0 };
220 m_context->timer.setTimerType(Qt::PreciseTimer);
221 updateTimerInterval();
223 m_context->elapsedTimer.start();
225 auto doGrab = [
this]() {
226 auto measure = m_context->profiler.measure();
228 auto frame = grabFrame();
230 if (frame.isValid()) {
231 frame.setStartTime(m_context->lastFrameTime);
232 frame.setEndTime(m_context->elapsedTimer.nsecsElapsed() / 1000);
233 m_context->lastFrameTime = frame.endTime();
235 updateError(QPlatformSurfaceCapture::Error::NoError);
237 Q_EMIT frameGrabbed(frame);
243 m_context->timer.callOnTimeout(&m_context->timer, doGrab);
244 m_context->timer.start();
249 Q_ASSERT(isGrabbingContextInitialized());
250 qCDebug(qLcScreenCaptureGrabber)
251 <<
"end screen capture thread; avg grabbing time:" << m_context->profiler.avgTime()
252 <<
"ms, grabbings number:" << m_context->profiler.number();
256 std::lock_guard locker{ m_mutex };
257 ++m_contextGeneration;
258 m_timerInterval = std::chrono::nanoseconds{ 0 };