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 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | static void qRegisterAbstractVideoBufferMetaTypes() |
50 | { |
51 | qRegisterMetaType<QAbstractVideoBuffer::HandleType>(); |
52 | qRegisterMetaType<QAbstractVideoBuffer::MapMode>(); |
53 | } |
54 | |
55 | Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoBufferMetaTypes) |
56 | |
57 | int 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 | */ |
131 | QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type) |
132 | : d_ptr(nullptr) |
133 | , m_type(type) |
134 | { |
135 | } |
136 | |
137 | /*! |
138 | \internal |
139 | */ |
140 | QAbstractVideoBuffer::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 | */ |
150 | QAbstractVideoBuffer::~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 | */ |
163 | void QAbstractVideoBuffer::release() |
164 | { |
165 | delete this; |
166 | } |
167 | |
168 | /*! |
169 | Returns the type of a video buffer's handle. |
170 | |
171 | \sa handle() |
172 | */ |
173 | QAbstractVideoBuffer::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 | */ |
241 | int 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 | */ |
270 | QVariant QAbstractVideoBuffer::handle() const |
271 | { |
272 | return QVariant(); |
273 | } |
274 | |
275 | |
276 | int 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 | */ |
302 | QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(HandleType type) |
303 | : QAbstractVideoBuffer(*new QAbstractPlanarVideoBufferPrivate, type) |
304 | { |
305 | } |
306 | |
307 | /*! |
308 | \internal |
309 | */ |
310 | QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer( |
311 | QAbstractPlanarVideoBufferPrivate &dd, HandleType type) |
312 | : QAbstractVideoBuffer(dd, type) |
313 | { |
314 | } |
315 | /*! |
316 | Destroys an abstract planar video buffer. |
317 | */ |
318 | QAbstractPlanarVideoBuffer::~QAbstractPlanarVideoBuffer() |
319 | { |
320 | } |
321 | |
322 | /*! |
323 | \internal |
324 | */ |
325 | uchar *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 |
360 | QDebug 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 | |
380 | QDebug 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 | |
397 | QT_END_NAMESPACE |
398 | |