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/qtconfigmacros.h>
19#include <QtMultimedia/qvideoframe.h>
20#include <QtMultimedia/qvideosink.h>
21
22#include <chrono>
23#include <optional>
24#include <vector>
25
26QT_BEGIN_NAMESPACE
27
28namespace QtMultimediaTest {
29
30// Generous timeout on CI, where machines are slow and heavily loaded. Short for
31// blacklisted test cases, which are expected to fail.
32[[nodiscard]] std::chrono::milliseconds surfaceCaptureTestTimeout();
33
42
43/*!
44 The FrameGrabber stores frames that arrive from a surface capture,
45 and is used to inspect captured frames in the tests.
46*/
48{
50
51public:
53
54 [[nodiscard]] const std::vector<VideoFrameInfo> &getFrameInfos() const;
55
56 /*!
57 Wait for at least \a minCount frames that are no older than noOlderThanTime.
58
59 If \a expectedFrameRate is given, the timeout is extended by one frame interval per
60 frame, rather than being a flat global timeout.
61
62 Returns empty if not enough frames arrived, or if grabber was stopped before global timeout
63 elapsed.
64 */
66 size_t minCount,
67 std::optional<qreal> expectedFrameRate = std::nullopt,
68 qint64 noOlderThanTime = 0);
69
70 /*!
71 Same as waitAndTakeFrameInfos(), but returns the video frames themselves.
72 Video frames are only retained for the duration of this call.
73 */
75 size_t minCount,
76 std::optional<qreal> expectedFrameRate = std::nullopt,
77 qint64 noOlderThanTime = 0);
78
79 /*!
80 Waits for the first frame of the current stream, and returns a copy of its
81 info. The capture becoming active marks the start of a new stream, so the
82 next valid frame after it is the first frame of that stream. Calling this
83 again within the same stream returns the same info.
84
85 Returns std::nullopt if no first frame arrived before the global timeout,
86 or if the grabber was stopped. Can never return an invalid frame.
87 */
88 [[nodiscard]] std::optional<VideoFrameInfo> tryWaitForFirstFrameInfo();
89
90 /*!
91 Same as tryWaitForFirstFrameInfo(), but returns the video frame itself, and
92 consumes it. The first frame of a stream is only kept alive if
93 setRetainFirstVideoFrame() was enabled before the stream started, since
94 holding on to frames can stall backends that use a fixed-size frame pool.
95 */
97
98 void setRetainFirstVideoFrame(bool retain);
99
100 /*!
101 Measures the average duration between \a frameCount consecutive frames.
102
103 If \a expectedFrameRate is given, a frame that takes significantly longer than
104 the frame interval to arrive ends the wait early. The first frame is still
105 allowed the global timeout, since backend initialization can delay it.
106
107 Returns std::nullopt if a frame stalled, or if not enough frames arrived.
108 */
109 [[nodiscard]] std::optional<std::chrono::milliseconds> durationBetweenFrames(
110 qsizetype frameCount = 1,
111 std::optional<qreal> expectedFrameRate = std::nullopt);
112
113 [[nodiscard]] bool isStopped() const;
114
115public slots:
116 void stop();
117
118 /*!
119 Starts tracking a new stream when the capture becomes active, so that
120 tryWaitForFirstFrameInfo() waits for the first frame of it.
121 */
122 void onCaptureActiveChanged(bool active);
123
124private:
125 void onFrameReceived(const QVideoFrame &frame);
126 [[nodiscard]] bool waitForFirstFrame();
127 void resetFirstFrame();
128
129 template <typename Frame>
130 [[nodiscard]] std::vector<Frame> waitAndTake(
131 std::vector<Frame> &frames,
132 size_t minCount,
133 std::optional<qreal> expectedFrameRate,
134 qint64 noOlderThanTime);
135
136 std::vector<VideoFrameInfo> m_frameInfos;
137
138 // Only set, and m_videoFrames only populated, during waitAndTakeVideoFrames().
139 bool m_retainVideoFrames = false;
140 std::vector<QVideoFrame> m_videoFrames;
141
142 // The first frame of the current stream, until it is consumed.
143 std::optional<VideoFrameInfo> m_firstFrameInfo;
144 // Same frame as above. Only populated if m_retainFirstVideoFrame is set.
145 bool m_retainFirstVideoFrame = false;
146 std::optional<QVideoFrame> m_firstVideoFrame;
147 // Whether we have received the first frame of the current stream.
148 bool m_streamStarted = false;
149
150 bool m_stopped = false;
151};
152
153} // namespace QtMultimediaTest
154
155QT_END_NAMESPACE
156
157#endif // FRAMEGRABBER_P_H
The FrameGrabber stores frames that arrive from a surface capture, and is used to inspect captured fr...
std::vector< QVideoFrame > waitAndTakeVideoFrames(size_t minCount, std::optional< qreal > expectedFrameRate=std::nullopt, qint64 noOlderThanTime=0)
Same as waitAndTakeFrameInfos(), but returns the video frames themselves.
void onCaptureActiveChanged(bool active)
Starts tracking a new stream when the capture becomes active, so that tryWaitForFirstFrameInfo() wait...
std::vector< VideoFrameInfo > waitAndTakeFrameInfos(size_t minCount, std::optional< qreal > expectedFrameRate=std::nullopt, qint64 noOlderThanTime=0)
Wait for at least minCount frames that are no older than noOlderThanTime.
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::optional< VideoFrameInfo > tryWaitForFirstFrameInfo()
Waits for the first frame of the current stream, and returns a copy of its info.
static std::optional< std::chrono::milliseconds > maxFrameInterval(std::optional< qreal > frameRate)
static qint64 startTimeOf(const VideoFrameInfo &info)
static VideoFrameInfo makeVideoFrameInfo(const QVideoFrame &frame)
std::chrono::milliseconds surfaceCaptureTestTimeout()
static qint64 startTimeOf(const QVideoFrame &frame)
QVideoFrameFormat::PixelFormat pixelFormat