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
framegenerator.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6#include <QtMultimedia/private/qplatformmediaintegration_p.h>
7#include <QtMultimedia/private/qmemoryvideobuffer_p.h>
8#include <QtMultimedia/private/qvideoframe_p.h>
9
10#include <QtCore/qbuffer.h>
11
13
14void VideoGenerator::setPattern(ImagePattern pattern)
15{
16 m_pattern = pattern;
17}
18
20{
21 m_maxFrameCount = count;
22}
23
24void VideoGenerator::setSize(QSize size)
25{
26 m_size = size;
27}
28
29void VideoGenerator::setPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
30{
31 m_pixelFormat = pixelFormat;
32}
33
34void VideoGenerator::setFrameRate(double rate)
35{
36 m_frameRate = rate;
37}
38
39void VideoGenerator::setPeriod(std::chrono::microseconds period)
40{
41 m_period = period;
42}
43
44void VideoGenerator::setPresentationRotation(QtVideo::Rotation rotation)
45{
46 m_presentationRotation = rotation;
47}
48
50{
51 m_presentationMirrored = mirror;
52}
53void VideoGenerator::setEndTimeReporting(bool endTimeIsReported)
54{
55 m_endTimeIsReported = endTimeIsReported;
56}
57
58void VideoGenerator::setColors(std::array<QColor, 5> newColors)
59{
60 m_colors = newColors;
61}
62
64{
65 m_emitEmptyFrameOnStop = true;
66}
67
68static void fillColoredSquares(QImage& image)
69{
70 QList<QColor> colors = { Qt::red, Qt::green, Qt::blue, Qt::yellow };
71 const int width = image.width();
72 const int height = image.height();
73
74 for (int j = 0; j < height; ++j) {
75 for (int i = 0; i < width; ++i) {
76 const int colorX = i < width / 2 ? 0 : 1;
77 const int colorY = j < height / 2 ? 0 : 1;
78 const int colorIndex = colorX + 2 * colorY;
79 image.setPixel(i, j, colors[colorIndex].rgb());
80 }
81 }
82}
83
84static QVideoFrame createJpegFrame(const QImage &image, QSize size)
85{
86 QByteArray jpegData;
87 QBuffer buffer(&jpegData);
88 if (!buffer.open(QIODevice::WriteOnly))
89 return {};
90
91 // Maximum quality, so that the comparison against the source image stays meaningful
92 if (!image.save(&buffer, "JPG", 100))
93 return {};
94
95 // JPEG frames hold the compressed data in a single plane without a line stride
96 auto videoBuffer = std::make_unique<QMemoryVideoBuffer>(std::move(jpegData), -1);
97 return QVideoFramePrivate::createFrame(std::move(videoBuffer),
98 QVideoFrameFormat(size, QVideoFrameFormat::Format_Jpeg));
99}
100
102{
103 using namespace std::chrono;
104
105 QImage image(m_size, QImage::Format_ARGB32);
106 switch (m_pattern) {
107 case ImagePattern::SingleColor:
108 image.fill(m_colors[m_frameIndex % m_colors.size()]);
109 break;
110 case ImagePattern::ColoredSquares:
111 fillColoredSquares(image);
112 break;
113 }
114
115 QVideoFrame frame;
116 if (m_pixelFormat == QVideoFrameFormat::Format_Jpeg) {
117 frame = createJpegFrame(image, m_size);
118 } else {
119 QVideoFrame rgbFrame(image);
120 QVideoFrameFormat outputFormat{ m_size, m_pixelFormat };
121 frame = QPlatformMediaIntegration::instance()->convertVideoFrame(rgbFrame, outputFormat);
122 }
123
124 if (m_frameRate)
125 frame.setStreamFrameRate(*m_frameRate);
126
127 if (m_period) {
128 frame.setStartTime(m_period->count() * m_frameIndex);
129 if (m_endTimeIsReported)
130 frame.setEndTime(m_period->count() * (m_frameIndex + 1));
131 }
132
133 if (m_presentationRotation)
134 frame.setRotation(*m_presentationRotation);
135
136 if (m_presentationMirrored)
137 frame.setMirrored(*m_presentationMirrored);
138
139 return frame;
140}
141
142void VideoGenerator::nextFrame()
143{
144 if (m_frameIndex == m_maxFrameCount) {
145 emit done();
146 if (m_emitEmptyFrameOnStop)
147 emit frameCreated({});
148 return;
149 }
150
151 const QVideoFrame frame = createFrame();
152 emit frameCreated(frame);
153 ++m_frameIndex;
154}
155
156QT_END_NAMESPACE
157
158#include "moc_framegenerator_p.cpp"
void setEndTimeReporting(bool endTimeIsReported)
QVideoFrame createFrame()
void setSize(QSize size)
void emitEmptyFrameOnStop()
void setPresentationMirrored(bool mirror)
void setColors(std::array< QColor, 5 > colors)
void setFrameCount(int count)
void setPeriod(std::chrono::microseconds period)
void setFrameRate(double rate)
void setPresentationRotation(QtVideo::Rotation rotation)
void setPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
static void fillColoredSquares(QImage &image)
static QVideoFrame createJpegFrame(const QImage &image, QSize size)
Combined button and popup list for selecting options.