1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qabstractvideobuffer_p.h"
41
42#include <qvariant.h>
43
44#include <QDebug>
45
46
47QT_BEGIN_NAMESPACE
48
49static void qRegisterAbstractVideoBufferMetaTypes()
50{
51 qRegisterMetaType<QAbstractVideoBuffer::HandleType>();
52 qRegisterMetaType<QAbstractVideoBuffer::MapMode>();
53}
54
55Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoBufferMetaTypes)
56
57int QAbstractVideoBufferPrivate::map(
58 QAbstractVideoBuffer::MapMode mode,
59 int *numBytes,
60 int bytesPerLine[4],
61 uchar *data[4])
62{
63 data[0] = q_ptr->map(mode, numBytes, bytesPerLine);
64 return data[0] ? 1 : 0;
65}
66
67/*!
68 \class QAbstractVideoBuffer
69 \brief The QAbstractVideoBuffer class is an abstraction for video data.
70 \inmodule QtMultimedia
71 \ingroup multimedia
72 \ingroup multimedia_video
73
74 The QVideoFrame class makes use of a QAbstractVideoBuffer internally to reference a buffer of
75 video data. Quite often video data buffers may reside in video memory rather than system
76 memory, and this class provides an abstraction of the location.
77
78 In addition, creating a subclass of QAbstractVideoBuffer will allow you to construct video
79 frames from preallocated or static buffers, in cases where the QVideoFrame constructors
80 taking a QByteArray or a QImage do not suffice. This may be necessary when implementing
81 a new hardware accelerated video system, for example.
82
83 The contents of a buffer can be accessed by mapping the buffer to memory using the map()
84 function, which returns a pointer to memory containing the contents of the video buffer.
85 The memory returned by map() is released by calling the unmap() function.
86
87 The handle() of a buffer may also be used to manipulate its contents using type specific APIs.
88 The type of a buffer's handle is given by the handleType() function.
89
90 \sa QVideoFrame
91*/
92
93/*!
94 \enum QAbstractVideoBuffer::HandleType
95
96 Identifies the type of a video buffers handle.
97
98 \value NoHandle The buffer has no handle, its data can only be accessed by mapping the buffer.
99 \value GLTextureHandle The handle of the buffer is an OpenGL texture ID.
100 \value XvShmImageHandle The handle contains pointer to shared memory XVideo image.
101 \value CoreImageHandle The handle contains pointer to \macos CIImage.
102 \value QPixmapHandle The handle of the buffer is a QPixmap.
103 \value EGLImageHandle The handle of the buffer is an EGLImageKHR.
104 \value UserHandle Start value for user defined handle types.
105
106 \sa handleType()
107*/
108
109/*!
110 \enum QAbstractVideoBuffer::MapMode
111
112 Enumerates how a video buffer's data is mapped to system memory.
113
114 \value NotMapped The video buffer is not mapped to memory.
115 \value ReadOnly The mapped memory is populated with data from the video buffer when mapped, but
116 the content of the mapped memory may be discarded when unmapped.
117 \value WriteOnly The mapped memory is uninitialized when mapped, but the possibly modified content
118 will be used to populate the video buffer when unmapped.
119 \value ReadWrite The mapped memory is populated with data from the video buffer, and the
120 video buffer is repopulated with the content of the mapped memory when it is unmapped.
121
122 \sa mapMode(), map()
123*/
124
125/*!
126 Constructs an abstract video buffer of the given \a type.
127*/
128QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type)
129 : d_ptr(nullptr)
130 , m_type(type)
131{
132}
133
134/*!
135 \internal
136*/
137QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type)
138 : d_ptr(&dd)
139 , m_type(type)
140{
141 d_ptr->q_ptr = this;
142}
143
144/*!
145 Destroys an abstract video buffer.
146*/
147QAbstractVideoBuffer::~QAbstractVideoBuffer()
148{
149 delete d_ptr;
150}
151
152/*!
153 Releases the video buffer.
154
155 QVideoFrame calls QAbstractVideoBuffer::release when the buffer is not used
156 any more and can be destroyed or returned to the buffer pool.
157
158 The default implementation deletes the buffer instance.
159*/
160void QAbstractVideoBuffer::release()
161{
162 delete this;
163}
164
165/*!
166 Returns the type of a video buffer's handle.
167
168 \sa handle()
169*/
170QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
171{
172 return m_type;
173}
174
175/*!
176 \fn QAbstractVideoBuffer::mapMode() const
177
178 Returns the mode a video buffer is mapped in.
179
180 \sa map()
181*/
182
183/*!
184 \fn QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
185
186 Maps the contents of a video buffer to memory.
187
188 In some cases the video buffer might be stored in video memory or otherwise inaccessible
189 memory, so it is necessary to map the buffer before accessing the pixel data. This may involve
190 copying the contents around, so avoid mapping and unmapping unless required.
191
192 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
193 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
194 mapped memory will be populated with the content of the buffer when initially mapped. If the map
195 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
196 mapped memory will be written back to the buffer when unmapped.
197
198 When access to the data is no longer needed be sure to call the unmap() function to release the
199 mapped memory and possibly update the buffer contents.
200
201 Returns a pointer to the mapped memory region, or a null pointer if the mapping failed. The
202 size in bytes of the mapped memory region is returned in \a numBytes, and the line stride in \a
203 bytesPerLine.
204
205 \note Writing to memory that is mapped as read-only is undefined, and may result in changes
206 to shared data or crashes.
207
208 \sa unmap(), mapMode()
209*/
210
211
212/*!
213 Independently maps the planes of a video buffer to memory.
214
215 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
216 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
217 mapped memory will be populated with the content of the buffer when initially mapped. If the map
218 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
219 mapped memory will be written back to the buffer when unmapped.
220
221 When access to the data is no longer needed be sure to call the unmap() function to release the
222 mapped memory and possibly update the buffer contents.
223
224 Returns the number of planes in the mapped video data. For each plane the line stride of that
225 plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
226 \a data. The accumulative size of the mapped data is returned in \a numBytes.
227
228 Not all buffer implementations will map more than the first plane, if this returns a single
229 plane for a planar format the additional planes will have to be calculated from the line stride
230 of the first plane and the frame height. Mapping a buffer with QVideoFrame will do this for
231 you.
232
233 To implement this function create a derivative of QAbstractPlanarVideoBuffer and implement
234 its map function instance instead.
235
236 \since 5.4
237*/
238int QAbstractVideoBuffer::mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
239{
240 if (d_ptr) {
241 return d_ptr->map(mode, numBytes, bytesPerLine, data);
242 } else {
243 data[0] = map(mode, numBytes, bytesPerLine);
244
245 return data[0] ? 1 : 0;
246 }
247}
248
249/*!
250 \fn QAbstractVideoBuffer::unmap()
251
252 Releases the memory mapped by the map() function.
253
254 If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the \c QAbstractVideoBuffer::WriteOnly
255 flag this will write the current content of the mapped memory back to the video frame.
256
257 \sa map()
258*/
259
260/*!
261 Returns a type specific handle to the data buffer.
262
263 The type of the handle is given by handleType() function.
264
265 \sa handleType()
266*/
267QVariant QAbstractVideoBuffer::handle() const
268{
269 return QVariant();
270}
271
272
273int QAbstractPlanarVideoBufferPrivate::map(
274 QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
275{
276 return q_func()->map(mode, numBytes, bytesPerLine, data);
277}
278
279/*!
280 \class QAbstractPlanarVideoBuffer
281 \brief The QAbstractPlanarVideoBuffer class is an abstraction for planar video data.
282 \inmodule QtMultimedia
283 \ingroup QtMultimedia
284 \ingroup multimedia
285 \ingroup multimedia_video
286
287 QAbstractPlanarVideoBuffer extends QAbstractVideoBuffer to support mapping
288 non-continuous planar video data. Implement this instead of QAbstractVideoBuffer when the
289 abstracted video data stores planes in separate buffers or includes padding between planes
290 which would interfere with calculating offsets from the bytes per line and frame height.
291
292 \sa QAbstractVideoBuffer::mapPlanes()
293 \since 5.4
294*/
295
296/*!
297 Constructs an abstract planar video buffer of the given \a type.
298*/
299QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(HandleType type)
300 : QAbstractVideoBuffer(*new QAbstractPlanarVideoBufferPrivate, type)
301{
302}
303
304/*!
305 \internal
306*/
307QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(
308 QAbstractPlanarVideoBufferPrivate &dd, HandleType type)
309 : QAbstractVideoBuffer(dd, type)
310{
311}
312/*!
313 Destroys an abstract planar video buffer.
314*/
315QAbstractPlanarVideoBuffer::~QAbstractPlanarVideoBuffer()
316{
317}
318
319/*!
320 \internal
321*/
322uchar *QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
323{
324 uchar *data[4];
325 int strides[4];
326 if (map(mode, numBytes, strides, data) > 0) {
327 if (bytesPerLine)
328 *bytesPerLine = strides[0];
329 return data[0];
330 } else {
331 return nullptr;
332 }
333}
334
335/*!
336 \fn int QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
337
338 Maps the contents of a video buffer to memory.
339
340 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
341 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
342 mapped memory will be populated with the content of the buffer when initially mapped. If the map
343 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
344 mapped memory will be written back to the buffer when unmapped.
345
346 When access to the data is no longer needed be sure to call the unmap() function to release the
347 mapped memory and possibly update the buffer contents.
348
349 Returns the number of planes in the mapped video data. For each plane the line stride of that
350 plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
351 \a data. The accumulative size of the mapped data is returned in \a numBytes.
352
353 \sa QAbstractVideoBuffer::map(), QAbstractVideoBuffer::unmap(), QAbstractVideoBuffer::mapMode()
354*/
355
356#ifndef QT_NO_DEBUG_STREAM
357QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::HandleType type)
358{
359 QDebugStateSaver saver(dbg);
360 dbg.nospace();
361 switch (type) {
362 case QAbstractVideoBuffer::NoHandle:
363 return dbg << "NoHandle";
364 case QAbstractVideoBuffer::GLTextureHandle:
365 return dbg << "GLTextureHandle";
366 case QAbstractVideoBuffer::XvShmImageHandle:
367 return dbg << "XvShmImageHandle";
368 case QAbstractVideoBuffer::CoreImageHandle:
369 return dbg << "CoreImageHandle";
370 case QAbstractVideoBuffer::QPixmapHandle:
371 return dbg << "QPixmapHandle";
372 default:
373 return dbg << "UserHandle(" << int(type) << ')';
374 }
375}
376
377QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::MapMode mode)
378{
379 QDebugStateSaver saver(dbg);
380 dbg.nospace();
381 switch (mode) {
382 case QAbstractVideoBuffer::ReadOnly:
383 return dbg << "ReadOnly";
384 case QAbstractVideoBuffer::ReadWrite:
385 return dbg << "ReadWrite";
386 case QAbstractVideoBuffer::WriteOnly:
387 return dbg << "WriteOnly";
388 default:
389 return dbg << "NotMapped";
390 }
391}
392#endif
393
394QT_END_NAMESPACE
395