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 of an undefined and platform dependent target type.
101 \value XvShmImageHandle The handle contains pointer to shared memory XVideo image.
102 \value CoreImageHandle The handle contains pointer to \macos CIImage.
103 \value QPixmapHandle The handle of the buffer is a QPixmap.
104 \value EGLImageHandle The handle of the buffer is an EGLImageKHR.
105 \value UserHandle Start value for user defined handle types.
106 \value GLTextureRectangleHandle The handle of the buffer is an OpenGL texture ID
107 of target type \c GL_TEXTURE_RECTANGLE.
108
109 \sa handleType()
110*/
111
112/*!
113 \enum QAbstractVideoBuffer::MapMode
114
115 Enumerates how a video buffer's data is mapped to system memory.
116
117 \value NotMapped The video buffer is not mapped to memory.
118 \value ReadOnly The mapped memory is populated with data from the video buffer when mapped, but
119 the content of the mapped memory may be discarded when unmapped.
120 \value WriteOnly The mapped memory is uninitialized when mapped, but the possibly modified content
121 will be used to populate the video buffer when unmapped.
122 \value ReadWrite The mapped memory is populated with data from the video buffer, and the
123 video buffer is repopulated with the content of the mapped memory when it is unmapped.
124
125 \sa mapMode(), map()
126*/
127
128/*!
129 Constructs an abstract video buffer of the given \a type.
130*/
131QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type)
132 : d_ptr(nullptr)
133 , m_type(type)
134{
135}
136
137/*!
138 \internal
139*/
140QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type)
141 : d_ptr(&dd)
142 , m_type(type)
143{
144 d_ptr->q_ptr = this;
145}
146
147/*!
148 Destroys an abstract video buffer.
149*/
150QAbstractVideoBuffer::~QAbstractVideoBuffer()
151{
152 delete d_ptr;
153}
154
155/*!
156 Releases the video buffer.
157
158 QVideoFrame calls QAbstractVideoBuffer::release when the buffer is not used
159 any more and can be destroyed or returned to the buffer pool.
160
161 The default implementation deletes the buffer instance.
162*/
163void QAbstractVideoBuffer::release()
164{
165 delete this;
166}
167
168/*!
169 Returns the type of a video buffer's handle.
170
171 \sa handle()
172*/
173QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
174{
175 return m_type;
176}
177
178/*!
179 \fn QAbstractVideoBuffer::mapMode() const
180
181 Returns the mode a video buffer is mapped in.
182
183 \sa map()
184*/
185
186/*!
187 \fn QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
188
189 Maps the contents of a video buffer to memory.
190
191 In some cases the video buffer might be stored in video memory or otherwise inaccessible
192 memory, so it is necessary to map the buffer before accessing the pixel data. This may involve
193 copying the contents around, so avoid mapping and unmapping unless required.
194
195 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
196 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
197 mapped memory will be populated with the content of the buffer when initially mapped. If the map
198 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
199 mapped memory will be written back to the buffer when unmapped.
200
201 When access to the data is no longer needed be sure to call the unmap() function to release the
202 mapped memory and possibly update the buffer contents.
203
204 Returns a pointer to the mapped memory region, or a null pointer if the mapping failed. The
205 size in bytes of the mapped memory region is returned in \a numBytes, and the line stride in \a
206 bytesPerLine.
207
208 \note Writing to memory that is mapped as read-only is undefined, and may result in changes
209 to shared data or crashes.
210
211 \sa unmap(), mapMode()
212*/
213
214
215/*!
216 Independently maps the planes of a video buffer to memory.
217
218 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
219 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
220 mapped memory will be populated with the content of the buffer when initially mapped. If the map
221 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
222 mapped memory will be written back to the buffer when unmapped.
223
224 When access to the data is no longer needed be sure to call the unmap() function to release the
225 mapped memory and possibly update the buffer contents.
226
227 Returns the number of planes in the mapped video data. For each plane the line stride of that
228 plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
229 \a data. The accumulative size of the mapped data is returned in \a numBytes.
230
231 Not all buffer implementations will map more than the first plane, if this returns a single
232 plane for a planar format the additional planes will have to be calculated from the line stride
233 of the first plane and the frame height. Mapping a buffer with QVideoFrame will do this for
234 you.
235
236 To implement this function create a derivative of QAbstractPlanarVideoBuffer and implement
237 its map function instance instead.
238
239 \since 5.4
240*/
241int QAbstractVideoBuffer::mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
242{
243 if (d_ptr) {
244 return d_ptr->map(mode, numBytes, bytesPerLine, data);
245 } else {
246 data[0] = map(mode, numBytes, bytesPerLine);
247
248 return data[0] ? 1 : 0;
249 }
250}
251
252/*!
253 \fn QAbstractVideoBuffer::unmap()
254
255 Releases the memory mapped by the map() function.
256
257 If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the \c QAbstractVideoBuffer::WriteOnly
258 flag this will write the current content of the mapped memory back to the video frame.
259
260 \sa map()
261*/
262
263/*!
264 Returns a type specific handle to the data buffer.
265
266 The type of the handle is given by handleType() function.
267
268 \sa handleType()
269*/
270QVariant QAbstractVideoBuffer::handle() const
271{
272 return QVariant();
273}
274
275
276int QAbstractPlanarVideoBufferPrivate::map(
277 QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
278{
279 return q_func()->map(mode, numBytes, bytesPerLine, data);
280}
281
282/*!
283 \class QAbstractPlanarVideoBuffer
284 \brief The QAbstractPlanarVideoBuffer class is an abstraction for planar video data.
285 \inmodule QtMultimedia
286 \ingroup QtMultimedia
287 \ingroup multimedia
288 \ingroup multimedia_video
289
290 QAbstractPlanarVideoBuffer extends QAbstractVideoBuffer to support mapping
291 non-continuous planar video data. Implement this instead of QAbstractVideoBuffer when the
292 abstracted video data stores planes in separate buffers or includes padding between planes
293 which would interfere with calculating offsets from the bytes per line and frame height.
294
295 \sa QAbstractVideoBuffer::mapPlanes()
296 \since 5.4
297*/
298
299/*!
300 Constructs an abstract planar video buffer of the given \a type.
301*/
302QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(HandleType type)
303 : QAbstractVideoBuffer(*new QAbstractPlanarVideoBufferPrivate, type)
304{
305}
306
307/*!
308 \internal
309*/
310QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(
311 QAbstractPlanarVideoBufferPrivate &dd, HandleType type)
312 : QAbstractVideoBuffer(dd, type)
313{
314}
315/*!
316 Destroys an abstract planar video buffer.
317*/
318QAbstractPlanarVideoBuffer::~QAbstractPlanarVideoBuffer()
319{
320}
321
322/*!
323 \internal
324*/
325uchar *QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
326{
327 uchar *data[4];
328 int strides[4];
329 if (map(mode, numBytes, bytesPerLine: strides, data) > 0) {
330 if (bytesPerLine)
331 *bytesPerLine = strides[0];
332 return data[0];
333 } else {
334 return nullptr;
335 }
336}
337
338/*!
339 \fn int QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
340
341 Maps the contents of a video buffer to memory.
342
343 The map \a mode indicates whether the contents of the mapped memory should be read from and/or
344 written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
345 mapped memory will be populated with the content of the buffer when initially mapped. If the map
346 mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
347 mapped memory will be written back to the buffer when unmapped.
348
349 When access to the data is no longer needed be sure to call the unmap() function to release the
350 mapped memory and possibly update the buffer contents.
351
352 Returns the number of planes in the mapped video data. For each plane the line stride of that
353 plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
354 \a data. The accumulative size of the mapped data is returned in \a numBytes.
355
356 \sa QAbstractVideoBuffer::map(), QAbstractVideoBuffer::unmap(), QAbstractVideoBuffer::mapMode()
357*/
358
359#ifndef QT_NO_DEBUG_STREAM
360QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::HandleType type)
361{
362 QDebugStateSaver saver(dbg);
363 dbg.nospace();
364 switch (type) {
365 case QAbstractVideoBuffer::NoHandle:
366 return dbg << "NoHandle";
367 case QAbstractVideoBuffer::GLTextureHandle:
368 return dbg << "GLTextureHandle";
369 case QAbstractVideoBuffer::XvShmImageHandle:
370 return dbg << "XvShmImageHandle";
371 case QAbstractVideoBuffer::CoreImageHandle:
372 return dbg << "CoreImageHandle";
373 case QAbstractVideoBuffer::QPixmapHandle:
374 return dbg << "QPixmapHandle";
375 default:
376 return dbg << "UserHandle(" << int(type) << ')';
377 }
378}
379
380QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::MapMode mode)
381{
382 QDebugStateSaver saver(dbg);
383 dbg.nospace();
384 switch (mode) {
385 case QAbstractVideoBuffer::ReadOnly:
386 return dbg << "ReadOnly";
387 case QAbstractVideoBuffer::ReadWrite:
388 return dbg << "ReadWrite";
389 case QAbstractVideoBuffer::WriteOnly:
390 return dbg << "WriteOnly";
391 default:
392 return dbg << "NotMapped";
393 }
394}
395#endif
396
397QT_END_NAMESPACE
398

source code of qtmultimedia/src/multimedia/video/qabstractvideobuffer.cpp