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
framegrabber_p.h
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef FRAMEGRABBER_P_H
5#define FRAMEGRABBER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qstring.h>
19#include <QtCore/qtconfigmacros.h>
20#include <QtMultimedia/qvideoframe.h>
21#include <QtMultimedia/qvideosink.h>
22
23#include <chrono>
24#include <optional>
25#include <vector>
26
27QT_BEGIN_NAMESPACE
28
29namespace QtMultimediaTest {
30
31// Generous timeout on CI, where machines are slow and heavily loaded. Short for
32// blacklisted test cases, which are expected to fail.
33[[nodiscard]] std::chrono::milliseconds surfaceCaptureTestTimeout();
34
36{
37 bool isValid = false;
40 std::optional<std::chrono::microseconds> startTime;
41 std::optional<std::chrono::microseconds> endTime;
43};
44
45[[nodiscard]] QString frameTimeToString(std::optional<std::chrono::microseconds> time);
46
47/*!
48 The FrameGrabber stores frames that arrive from a surface capture,
49 and is used to inspect captured frames in the tests.
50*/
52{
54
55public:
57
58 [[nodiscard]] const std::vector<VideoFrameInfo> &getFrameInfos() const;
59
60 /*!
61 Wait for at least \a minCount frames that are no older than noOlderThanTime.
62
63 If \a expectedFrameRate is given, the timeout is extended by one frame interval per
64 frame, rather than being a flat global timeout.
65
66 Returns empty if not enough frames arrived, or if grabber was stopped before global timeout
67 elapsed.
68 */
70 size_t minCount,
71 std::optional<qreal> expectedFrameRate = std::nullopt,
72 std::optional<std::chrono::microseconds> noOlderThanTime = std::nullopt);
73
74 /*!
75 Same as waitAndTakeFrameInfos(), but returns the video frames themselves.
76 Video frames are only retained for the duration of this call.
77 */
79 size_t minCount,
80 std::optional<qreal> expectedFrameRate = std::nullopt,
81 std::optional<std::chrono::microseconds> noOlderThanTime = std::nullopt);
82
83 /*!
84 Waits for the first frame of the current stream, and returns a copy of its
85 info. The capture becoming active marks the start of a new stream, so the
86 next valid frame after it is the first frame of that stream. Calling this
87 again within the same stream returns the same info.
88
89 Returns std::nullopt if no first frame arrived before the global timeout,
90 or if the grabber was stopped. Can never return an invalid frame.
91 */
92 [[nodiscard]] std::optional<VideoFrameInfo> tryWaitForFirstFrameInfo();
93
94 /*!
95 Same as tryWaitForFirstFrameInfo(), but returns the video frame itself, and
96 consumes it. The first frame of a stream is only kept alive if
97 setRetainFirstVideoFrame() was enabled before the stream started, since
98 holding on to frames can stall backends that use a fixed-size frame pool.
99 */
101
102 void setRetainFirstVideoFrame(bool retain);
103
104 /*!
105 Measures the average duration between \a frameCount consecutive frames.
106
107 If \a expectedFrameRate is given, a frame that takes significantly longer than
108 the frame interval to arrive ends the wait early. The first frame is still
109 allowed the global timeout, since backend initialization can delay it.
110
111 Returns std::nullopt if a frame stalled, or if not enough frames arrived.
112 */
113 [[nodiscard]] std::optional<std::chrono::milliseconds> durationBetweenFrames(
114 qsizetype frameCount = 1,
115 std::optional<qreal> expectedFrameRate = std::nullopt);
116
117 [[nodiscard]] bool isStopped() const;
118
119public slots:
120 void stop();
121
122 /*!
123 Starts tracking a new stream when the capture becomes active, so that
124 tryWaitForFirstFrameInfo() waits for the first frame of it.
125 */
126 void onCaptureActiveChanged(bool active);
127
128private:
129 void onFrameReceived(const QVideoFrame &frame);
130 [[nodiscard]] bool waitForFirstFrame();
131 void resetFirstFrame();
132
133 template <typename Frame>
134 [[nodiscard]] std::vector<Frame> waitAndTake(
135 std::vector<Frame> &frames,
136 size_t minCount,
137 std::optional<qreal> expectedFrameRate,
138 std::optional<std::chrono::microseconds> noOlderThanTime);
139
140 std::vector<VideoFrameInfo> m_frameInfos;
141
142 // Only set, and m_videoFrames only populated, during waitAndTakeVideoFrames().
143 bool m_retainVideoFrames = false;
144 std::vector<QVideoFrame> m_videoFrames;
145
146 // The first frame of the current stream, until it is consumed.
147 std::optional<VideoFrameInfo> m_firstFrameInfo;
148 // Same frame as above. Only populated if m_retainFirstVideoFrame is set.
149 bool m_retainFirstVideoFrame = false;
150 std::optional<QVideoFrame> m_firstVideoFrame;
151 // Whether we have received the first frame of the current stream.
152 bool m_streamStarted = false;
153
154 bool m_stopped = false;
155};
156
157} // namespace QtMultimediaTest
158
159QT_END_NAMESPACE
160
161#endif // FRAMEGRABBER_P_H
The FrameGrabber stores frames that arrive from a surface capture, and is used to inspect captured fr...
void onCaptureActiveChanged(bool active)
Starts tracking a new stream when the capture becomes active, so that tryWaitForFirstFrameInfo() wait...
void setRetainFirstVideoFrame(bool retain)
std::optional< std::chrono::milliseconds > durationBetweenFrames(qsizetype frameCount=1, std::optional< qreal > expectedFrameRate=std::nullopt)
Measures the average duration between frameCount consecutive frames.
const std::vector< VideoFrameInfo > & getFrameInfos() const
std::optional< QVideoFrame > consumeFirstVideoFrame()
Same as tryWaitForFirstFrameInfo(), but returns the video frame itself, and consumes it.
std::vector< QVideoFrame > waitAndTakeVideoFrames(size_t minCount, std::optional< qreal > expectedFrameRate=std::nullopt, std::optional< std::chrono::microseconds > noOlderThanTime=std::nullopt)
Same as waitAndTakeFrameInfos(), but returns the video frames themselves.
std::optional< VideoFrameInfo > tryWaitForFirstFrameInfo()
Waits for the first frame of the current stream, and returns a copy of its info.
std::vector< VideoFrameInfo > waitAndTakeFrameInfos(size_t minCount, std::optional< qreal > expectedFrameRate=std::nullopt, std::optional< std::chrono::microseconds > noOlderThanTime=std::nullopt)
Wait for at least minCount frames that are no older than noOlderThanTime.
static std::optional< std::chrono::milliseconds > maxFrameInterval(std::optional< qreal > frameRate)
static std::optional< std::chrono::microseconds > startTimeOf(const QVideoFrame &frame)
static std::optional< std::chrono::microseconds > startTimeOf(const VideoFrameInfo &info)
static VideoFrameInfo makeVideoFrameInfo(const QVideoFrame &frame)
std::chrono::milliseconds surfaceCaptureTestTimeout()
QString frameTimeToString(std::optional< std::chrono::microseconds > time)
static std::optional< std::chrono::microseconds > toFrameTime(qint64 time)
std::optional< std::chrono::microseconds > startTime
std::optional< std::chrono::microseconds > endTime
QVideoFrameFormat::PixelFormat pixelFormat