summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/multimedia/video/qmlvideofilter_opencl/rgbframehelper.h2
-rw-r--r--src/gsttools/qgstvideobuffer.cpp31
-rw-r--r--src/gsttools/qgstvideobuffer_p.h4
-rw-r--r--src/multimedia/video/qabstractvideobuffer.cpp115
-rw-r--r--src/multimedia/video/qabstractvideobuffer.h32
-rw-r--r--src/multimedia/video/qabstractvideobuffer_p.h27
-rw-r--r--src/multimedia/video/qimagevideobuffer.cpp16
-rw-r--r--src/multimedia/video/qimagevideobuffer_p.h2
-rw-r--r--src/multimedia/video/qmemoryvideobuffer.cpp16
-rw-r--r--src/multimedia/video/qmemoryvideobuffer_p.h2
-rw-r--r--src/multimedia/video/qvideoframe.cpp192
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.cpp24
-rw-r--r--src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm46
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm2
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.cpp23
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp11
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp20
-rw-r--r--tests/auto/unit/qabstractvideobuffer/tst_qabstractvideobuffer.cpp2
-rw-r--r--tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp4
-rw-r--r--tests/auto/unit/qvideoframe/tst_qvideoframe.cpp42
20 files changed, 218 insertions, 395 deletions
diff --git a/examples/multimedia/video/qmlvideofilter_opencl/rgbframehelper.h b/examples/multimedia/video/qmlvideofilter_opencl/rgbframehelper.h
index 1c8dbd857..638337ea4 100644
--- a/examples/multimedia/video/qmlvideofilter_opencl/rgbframehelper.h
+++ b/examples/multimedia/video/qmlvideofilter_opencl/rgbframehelper.h
@@ -113,7 +113,7 @@ class TextureBuffer : public QAbstractVideoBuffer
public:
TextureBuffer(uint id) : QAbstractVideoBuffer(GLTextureHandle), m_id(id) { }
MapMode mapMode() const { return NotMapped; }
- uchar *map(MapMode, int *, int *) { return 0; }
+ virtual MapData map(MapMode mode) { return {}; }
void unmap() { }
QVariant handle() const { return QVariant::fromValue<uint>(m_id); }
diff --git a/src/gsttools/qgstvideobuffer.cpp b/src/gsttools/qgstvideobuffer.cpp
index 49c8efaed..58738ffa0 100644
--- a/src/gsttools/qgstvideobuffer.cpp
+++ b/src/gsttools/qgstvideobuffer.cpp
@@ -42,7 +42,7 @@
QT_BEGIN_NAMESPACE
QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info)
- : QAbstractPlanarVideoBuffer(NoHandle)
+ : QAbstractVideoBuffer(NoHandle)
, m_videoInfo(info)
, m_buffer(buffer)
{
@@ -52,7 +52,7 @@ QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info)
QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info,
QGstVideoBuffer::HandleType handleType,
const QVariant &handle)
- : QAbstractPlanarVideoBuffer(handleType)
+ : QAbstractVideoBuffer(handleType)
, m_videoInfo(info)
, m_buffer(buffer)
, m_handle(handle)
@@ -73,39 +73,36 @@ QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const
return m_mode;
}
-int QGstVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
+QAbstractVideoBuffer::MapData QGstVideoBuffer::map(MapMode mode)
{
const GstMapFlags flags = GstMapFlags(((mode & ReadOnly) ? GST_MAP_READ : 0)
| ((mode & WriteOnly) ? GST_MAP_WRITE : 0));
+ MapData mapData;
if (mode == NotMapped || m_mode != NotMapped)
- return 0;
+ return mapData;
if (m_videoInfo.finfo->n_planes == 0) { // Encoded
if (gst_buffer_map(m_buffer, &m_frame.map[0], flags)) {
- if (numBytes)
- *numBytes = m_frame.map[0].size;
- bytesPerLine[0] = -1;
- data[0] = static_cast<uchar *>(m_frame.map[0].data);
+ mapData.nBytes = m_frame.map[0].size;
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = -1;
+ mapData.data[0] = static_cast<uchar *>(m_frame.map[0].data);
m_mode = mode;
-
- return 1;
}
} else if (gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, flags)) {
- if (numBytes)
- *numBytes = m_frame.info.size;
+ mapData.nBytes = m_frame.info.size;
+ mapData.nPlanes = m_frame.info.finfo->n_planes;
for (guint i = 0; i < m_frame.info.finfo->n_planes; ++i) {
- bytesPerLine[i] = m_frame.info.stride[i];
- data[i] = static_cast<uchar *>(m_frame.data[i]);
+ mapData.bytesPerLine[i] = m_frame.info.stride[i];
+ mapData.data[i] = static_cast<uchar *>(m_frame.data[i]);
}
m_mode = mode;
-
- return m_frame.info.finfo->n_planes;
}
- return 0;
+ return mapData;
}
void QGstVideoBuffer::unmap()
diff --git a/src/gsttools/qgstvideobuffer_p.h b/src/gsttools/qgstvideobuffer_p.h
index 5f026ebc5..4dc45a370 100644
--- a/src/gsttools/qgstvideobuffer_p.h
+++ b/src/gsttools/qgstvideobuffer_p.h
@@ -60,7 +60,7 @@
QT_BEGIN_NAMESPACE
-class Q_GSTTOOLS_EXPORT QGstVideoBuffer : public QAbstractPlanarVideoBuffer
+class Q_GSTTOOLS_EXPORT QGstVideoBuffer : public QAbstractVideoBuffer
{
public:
QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info);
@@ -72,7 +72,7 @@ public:
GstBuffer *buffer() const { return m_buffer; }
MapMode mapMode() const override;
- int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) override;
+ MapData map(MapMode mode) override;
void unmap() override;
QVariant handle() const override { return m_handle; }
diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp
index 40493412b..0a56902b0 100644
--- a/src/multimedia/video/qabstractvideobuffer.cpp
+++ b/src/multimedia/video/qabstractvideobuffer.cpp
@@ -54,16 +54,6 @@ static void qRegisterAbstractVideoBufferMetaTypes()
Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoBufferMetaTypes)
-int QAbstractVideoBufferPrivate::map(
- QAbstractVideoBuffer::MapMode mode,
- int *numBytes,
- int bytesPerLine[4],
- uchar *data[4])
-{
- data[0] = q_ptr->map(mode, numBytes, bytesPerLine);
- return data[0] ? 1 : 0;
-}
-
/*!
\class QAbstractVideoBuffer
\brief The QAbstractVideoBuffer class is an abstraction for video data.
@@ -127,8 +117,7 @@ int QAbstractVideoBufferPrivate::map(
Constructs an abstract video buffer of the given \a type.
*/
QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type)
- : d_ptr(nullptr)
- , m_type(type)
+ : m_type(type)
{
}
@@ -181,36 +170,8 @@ QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
\sa map()
*/
-/*!
- \fn QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
-
- Maps the contents of a video buffer to memory.
-
- In some cases the video buffer might be stored in video memory or otherwise inaccessible
- memory, so it is necessary to map the buffer before accessing the pixel data. This may involve
- copying the contents around, so avoid mapping and unmapping unless required.
-
- The map \a mode indicates whether the contents of the mapped memory should be read from and/or
- written to the buffer. If the map mode includes the \c QAbstractVideoBuffer::ReadOnly flag the
- mapped memory will be populated with the content of the buffer when initially mapped. If the map
- mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
- mapped memory will be written back to the buffer when unmapped.
-
- When access to the data is no longer needed be sure to call the unmap() function to release the
- mapped memory and possibly update the buffer contents.
-
- Returns a pointer to the mapped memory region, or a null pointer if the mapping failed. The
- size in bytes of the mapped memory region is returned in \a numBytes, and the line stride in \a
- bytesPerLine.
-
- \note Writing to memory that is mapped as read-only is undefined, and may result in changes
- to shared data or crashes.
-
- \sa unmap(), mapMode()
-*/
-
+/*! \fn uchar *QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
-/*!
Independently maps the planes of a video buffer to memory.
The map \a mode indicates whether the contents of the mapped memory should be read from and/or
@@ -236,15 +197,6 @@ QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
\since 5.4
*/
-int QAbstractVideoBuffer::mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
-{
- if (d_ptr)
- return d_ptr->map(mode, numBytes, bytesPerLine, data);
-
- data[0] = map(mode, numBytes, bytesPerLine);
-
- return data[0] ? 1 : 0;
-}
/*!
\fn QAbstractVideoBuffer::unmap()
@@ -269,69 +221,6 @@ QVariant QAbstractVideoBuffer::handle() const
return QVariant();
}
-
-int QAbstractPlanarVideoBufferPrivate::map(
- QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
-{
- return q_func()->map(mode, numBytes, bytesPerLine, data);
-}
-
-/*!
- \class QAbstractPlanarVideoBuffer
- \brief The QAbstractPlanarVideoBuffer class is an abstraction for planar video data.
- \inmodule QtMultimedia
- \ingroup QtMultimedia
- \ingroup multimedia
- \ingroup multimedia_video
-
- QAbstractPlanarVideoBuffer extends QAbstractVideoBuffer to support mapping
- non-continuous planar video data. Implement this instead of QAbstractVideoBuffer when the
- abstracted video data stores planes in separate buffers or includes padding between planes
- which would interfere with calculating offsets from the bytes per line and frame height.
-
- \sa QAbstractVideoBuffer::mapPlanes()
- \since 5.4
-*/
-
-/*!
- Constructs an abstract planar video buffer of the given \a type.
-*/
-QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(HandleType type)
- : QAbstractVideoBuffer(*new QAbstractPlanarVideoBufferPrivate, type)
-{
-}
-
-/*!
- \internal
-*/
-QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(
- QAbstractPlanarVideoBufferPrivate &dd, HandleType type)
- : QAbstractVideoBuffer(dd, type)
-{
-}
-/*!
- Destroys an abstract planar video buffer.
-*/
-QAbstractPlanarVideoBuffer::~QAbstractPlanarVideoBuffer()
-{
-}
-
-/*!
- \internal
-*/
-uchar *QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
-{
- uchar *data[4];
- int strides[4];
- if (map(mode, numBytes, strides, data) > 0) {
- if (bytesPerLine)
- *bytesPerLine = strides[0];
- return data[0];
- }
-
- return nullptr;
-}
-
/*!
\fn int QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h
index b3f31b377..6572db9c3 100644
--- a/src/multimedia/video/qabstractvideobuffer.h
+++ b/src/multimedia/video/qabstractvideobuffer.h
@@ -82,10 +82,16 @@ public:
HandleType handleType() const;
- virtual MapMode mapMode() const = 0;
+ struct MapData
+ {
+ qsizetype nBytes = 0;
+ int nPlanes = 0;
+ int bytesPerLine[4] = {};
+ uchar *data[4] = {};
+ };
- virtual uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) = 0;
- int mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]);
+ virtual MapMode mapMode() const = 0;
+ virtual MapData map(MapMode mode) = 0;
virtual void unmap() = 0;
virtual QVariant handle() const;
@@ -93,31 +99,13 @@ public:
protected:
QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type);
- QAbstractVideoBufferPrivate *d_ptr; // For expansion, not used currently
+ QAbstractVideoBufferPrivate *d_ptr = nullptr; // currently unused
HandleType m_type;
private:
- Q_DECLARE_PRIVATE(QAbstractVideoBuffer)
Q_DISABLE_COPY(QAbstractVideoBuffer)
};
-class QAbstractPlanarVideoBufferPrivate;
-class Q_MULTIMEDIA_EXPORT QAbstractPlanarVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- QAbstractPlanarVideoBuffer(HandleType type);
- virtual ~QAbstractPlanarVideoBuffer();
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override;
- virtual int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) = 0;
-
-protected:
- QAbstractPlanarVideoBuffer(QAbstractPlanarVideoBufferPrivate &dd, HandleType type);
-
-private:
- Q_DISABLE_COPY(QAbstractPlanarVideoBuffer)
-};
-
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAbstractVideoBuffer::HandleType);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAbstractVideoBuffer::MapMode);
diff --git a/src/multimedia/video/qabstractvideobuffer_p.h b/src/multimedia/video/qabstractvideobuffer_p.h
index 4877d3120..ff3f5e0ba 100644
--- a/src/multimedia/video/qabstractvideobuffer_p.h
+++ b/src/multimedia/video/qabstractvideobuffer_p.h
@@ -63,32 +63,7 @@ QT_BEGIN_NAMESPACE
class QAbstractVideoBufferPrivate
{
public:
- QAbstractVideoBufferPrivate()
- : q_ptr(nullptr)
- {}
-
- virtual ~QAbstractVideoBufferPrivate()
- {}
-
- virtual int map(
- QAbstractVideoBuffer::MapMode mode,
- int *numBytes,
- int bytesPerLine[4],
- uchar *data[4]);
-
- QAbstractVideoBuffer *q_ptr;
-};
-
-class QAbstractPlanarVideoBufferPrivate : QAbstractVideoBufferPrivate
-{
-public:
- QAbstractPlanarVideoBufferPrivate()
- {}
-
- int map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) override;
-
-private:
- Q_DECLARE_PUBLIC(QAbstractPlanarVideoBuffer)
+ QAbstractVideoBuffer *q_ptr = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/video/qimagevideobuffer.cpp b/src/multimedia/video/qimagevideobuffer.cpp
index ad2de82e6..2602d7d9e 100644
--- a/src/multimedia/video/qimagevideobuffer.cpp
+++ b/src/multimedia/video/qimagevideobuffer.cpp
@@ -76,23 +76,21 @@ QAbstractVideoBuffer::MapMode QImageVideoBuffer::mapMode() const
return d_func()->mapMode;
}
-uchar *QImageVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+QImageVideoBuffer::MapData QImageVideoBuffer::map(MapMode mode)
{
Q_D(QImageVideoBuffer);
+ MapData mapData;
if (d->mapMode == NotMapped && d->image.bits() && mode != NotMapped) {
d->mapMode = mode;
- if (numBytes)
- *numBytes = int(d->image.sizeInBytes());
-
- if (bytesPerLine)
- *bytesPerLine = d->image.bytesPerLine();
-
- return d->image.bits();
+ mapData.nBytes = int(d->image.sizeInBytes());
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = d->image.bytesPerLine();
+ mapData.data[0] = d->image.bits();
}
- return nullptr;
+ return mapData;
}
void QImageVideoBuffer::unmap()
diff --git a/src/multimedia/video/qimagevideobuffer_p.h b/src/multimedia/video/qimagevideobuffer_p.h
index f2b88dd9b..ba980a3fb 100644
--- a/src/multimedia/video/qimagevideobuffer_p.h
+++ b/src/multimedia/video/qimagevideobuffer_p.h
@@ -69,7 +69,7 @@ public:
MapMode mapMode() const override;
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override;
+ MapData map(MapMode mode) override;
void unmap() override;
};
diff --git a/src/multimedia/video/qmemoryvideobuffer.cpp b/src/multimedia/video/qmemoryvideobuffer.cpp
index caab74e58..164aa6ebc 100644
--- a/src/multimedia/video/qmemoryvideobuffer.cpp
+++ b/src/multimedia/video/qmemoryvideobuffer.cpp
@@ -91,23 +91,21 @@ QAbstractVideoBuffer::MapMode QMemoryVideoBuffer::mapMode() const
/*!
\reimp
*/
-uchar *QMemoryVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+QAbstractVideoBuffer::MapData QMemoryVideoBuffer::map(MapMode mode)
{
Q_D(QMemoryVideoBuffer);
+ MapData mapData;
if (d->mapMode == NotMapped && d->data.size() && mode != NotMapped) {
d->mapMode = mode;
- if (numBytes)
- *numBytes = d->data.size();
-
- if (bytesPerLine)
- *bytesPerLine = d->bytesPerLine;
-
- return reinterpret_cast<uchar *>(d->data.data());
+ mapData.nBytes = d->data.size();
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = d->bytesPerLine;
+ mapData.data[0] = reinterpret_cast<uchar *>(d->data.data());
}
- return nullptr;
+ return mapData;
}
/*!
diff --git a/src/multimedia/video/qmemoryvideobuffer_p.h b/src/multimedia/video/qmemoryvideobuffer_p.h
index e1b1f83a9..5251b4979 100644
--- a/src/multimedia/video/qmemoryvideobuffer_p.h
+++ b/src/multimedia/video/qmemoryvideobuffer_p.h
@@ -67,7 +67,7 @@ public:
MapMode mapMode() const override;
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override;
+ MapData map(MapMode mode) override;
void unmap() override;
};
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp
index 6adbbdeb1..d7ddfb5e0 100644
--- a/src/multimedia/video/qvideoframe.cpp
+++ b/src/multimedia/video/qvideoframe.cpp
@@ -67,16 +67,12 @@ class QVideoFramePrivate : public QSharedData
public:
QVideoFramePrivate()
{
- memset(data, 0, sizeof(data));
- memset(bytesPerLine, 0, sizeof(bytesPerLine));
}
QVideoFramePrivate(const QSize &size, QVideoFrame::PixelFormat format)
: size(size)
, pixelFormat(format)
{
- memset(data, 0, sizeof(data));
- memset(bytesPerLine, 0, sizeof(bytesPerLine));
}
~QVideoFramePrivate()
@@ -88,10 +84,7 @@ public:
QSize size;
qint64 startTime = -1;
qint64 endTime = -1;
- uchar *data[4];
- int bytesPerLine[4];
- int mappedBytes = 0;
- int planeCount = 0;
+ QAbstractVideoBuffer::MapData mapData;
QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
QAbstractVideoBuffer *buffer = nullptr;
int mappedCount = 0;
@@ -553,89 +546,90 @@ bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
return false;
}
- Q_ASSERT(d->data[0] == nullptr);
- Q_ASSERT(d->bytesPerLine[0] == 0);
- Q_ASSERT(d->planeCount == 0);
- Q_ASSERT(d->mappedBytes == 0);
+ Q_ASSERT(d->mapData.data[0] == nullptr);
+ Q_ASSERT(d->mapData.bytesPerLine[0] == 0);
+ Q_ASSERT(d->mapData.nPlanes == 0);
+ Q_ASSERT(d->mapData.nBytes == 0);
- d->planeCount = d->buffer->mapPlanes(mode, &d->mappedBytes, d->bytesPerLine, d->data);
- if (d->planeCount == 0)
+ d->mapData = d->buffer->map(mode);
+ if (d->mapData.nPlanes == 0)
return false;
- if (d->planeCount > 1) {
- // If the plane count is derive the additional planes for planar formats.
- } else switch (d->pixelFormat) {
- case Format_Invalid:
- case Format_ARGB32:
- case Format_ARGB32_Premultiplied:
- case Format_RGB32:
- case Format_RGB24:
- case Format_RGB565:
- case Format_RGB555:
- case Format_ARGB8565_Premultiplied:
- case Format_BGRA32:
- case Format_BGRA32_Premultiplied:
- case Format_ABGR32:
- case Format_BGR32:
- case Format_BGR24:
- case Format_BGR565:
- case Format_BGR555:
- case Format_BGRA5658_Premultiplied:
- case Format_AYUV444:
- case Format_AYUV444_Premultiplied:
- case Format_YUV444:
- case Format_UYVY:
- case Format_YUYV:
- case Format_Y8:
- case Format_Y16:
- case Format_Jpeg:
- case Format_CameraRaw:
- case Format_AdobeDng:
- case Format_User:
- // Single plane or opaque format.
- break;
- case Format_YUV420P:
- case Format_YUV422P:
- case Format_YV12: {
- // The UV stride is usually half the Y stride and is 32-bit aligned.
- // However it's not always the case, at least on Windows where the
- // UV planes are sometimes not aligned.
- // We calculate the stride using the UV byte count to always
- // have a correct stride.
- const int height = d->size.height();
- const int yStride = d->bytesPerLine[0];
- const int uvHeight = d->pixelFormat == Format_YUV422P ? height : height / 2;
- const int uvStride = (d->mappedBytes - (yStride * height)) / uvHeight / 2;
-
- // Three planes, the second and third vertically (and horizontally for other than Format_YUV422P formats) subsampled.
- d->planeCount = 3;
- d->bytesPerLine[2] = d->bytesPerLine[1] = uvStride;
- d->data[1] = d->data[0] + (yStride * height);
- d->data[2] = d->data[1] + (uvStride * uvHeight);
- break;
- }
- case Format_NV12:
- case Format_NV21:
- case Format_IMC2:
- case Format_IMC4: {
- // Semi planar, Full resolution Y plane with interleaved subsampled U and V planes.
- d->planeCount = 2;
- d->bytesPerLine[1] = d->bytesPerLine[0];
- d->data[1] = d->data[0] + (d->bytesPerLine[0] * d->size.height());
- break;
- }
- case Format_IMC1:
- case Format_IMC3: {
- // Three planes, the second and third vertically and horizontally subsumpled,
- // but with lines padded to the width of the first plane.
- d->planeCount = 3;
- d->bytesPerLine[2] = d->bytesPerLine[1] = d->bytesPerLine[0];
- d->data[1] = d->data[0] + (d->bytesPerLine[0] * d->size.height());
- d->data[2] = d->data[1] + (d->bytesPerLine[1] * d->size.height() / 2);
- break;
- }
- default:
- break;
+ if (d->mapData.nPlanes == 1) {
+ // If the plane count is 1 derive the additional planes for planar formats.
+ switch (d->pixelFormat) {
+ case Format_Invalid:
+ case Format_ARGB32:
+ case Format_ARGB32_Premultiplied:
+ case Format_RGB32:
+ case Format_RGB24:
+ case Format_RGB565:
+ case Format_RGB555:
+ case Format_ARGB8565_Premultiplied:
+ case Format_BGRA32:
+ case Format_BGRA32_Premultiplied:
+ case Format_ABGR32:
+ case Format_BGR32:
+ case Format_BGR24:
+ case Format_BGR565:
+ case Format_BGR555:
+ case Format_BGRA5658_Premultiplied:
+ case Format_AYUV444:
+ case Format_AYUV444_Premultiplied:
+ case Format_YUV444:
+ case Format_UYVY:
+ case Format_YUYV:
+ case Format_Y8:
+ case Format_Y16:
+ case Format_Jpeg:
+ case Format_CameraRaw:
+ case Format_AdobeDng:
+ case Format_User:
+ // Single plane or opaque format.
+ break;
+ case Format_YUV420P:
+ case Format_YUV422P:
+ case Format_YV12: {
+ // The UV stride is usually half the Y stride and is 32-bit aligned.
+ // However it's not always the case, at least on Windows where the
+ // UV planes are sometimes not aligned.
+ // We calculate the stride using the UV byte count to always
+ // have a correct stride.
+ const int height = d->size.height();
+ const int yStride = d->mapData.bytesPerLine[0];
+ const int uvHeight = d->pixelFormat == Format_YUV422P ? height : height / 2;
+ const int uvStride = (d->mapData.nBytes - (yStride * height)) / uvHeight / 2;
+
+ // Three planes, the second and third vertically (and horizontally for other than Format_YUV422P formats) subsampled.
+ d->mapData.nPlanes = 3;
+ d->mapData.bytesPerLine[2] = d->mapData.bytesPerLine[1] = uvStride;
+ d->mapData.data[1] = d->mapData.data[0] + (yStride * height);
+ d->mapData.data[2] = d->mapData.data[1] + (uvStride * uvHeight);
+ break;
+ }
+ case Format_NV12:
+ case Format_NV21:
+ case Format_IMC2:
+ case Format_IMC4: {
+ // Semi planar, Full resolution Y plane with interleaved subsampled U and V planes.
+ d->mapData.nPlanes = 2;
+ d->mapData.bytesPerLine[1] = d->mapData.bytesPerLine[0];
+ d->mapData.data[1] = d->mapData.data[0] + (d->mapData.bytesPerLine[0] * d->size.height());
+ break;
+ }
+ case Format_IMC1:
+ case Format_IMC3: {
+ // Three planes, the second and third vertically and horizontally subsumpled,
+ // but with lines padded to the width of the first plane.
+ d->mapData.nPlanes = 3;
+ d->mapData.bytesPerLine[2] = d->mapData.bytesPerLine[1] = d->mapData.bytesPerLine[0];
+ d->mapData.data[1] = d->mapData.data[0] + (d->mapData.bytesPerLine[0] * d->size.height());
+ d->mapData.data[2] = d->mapData.data[1] + (d->mapData.bytesPerLine[1] * d->size.height() / 2);
+ break;
+ }
+ default:
+ break;
+ }
}
d->mappedCount++;
@@ -667,11 +661,7 @@ void QVideoFrame::unmap()
d->mappedCount--;
if (d->mappedCount == 0) {
- d->mappedBytes = 0;
- d->planeCount = 0;
- memset(d->bytesPerLine, 0, sizeof(d->bytesPerLine));
- memset(d->data, 0, sizeof(d->data));
-
+ d->mapData = {};
d->buffer->unmap();
}
}
@@ -688,7 +678,7 @@ void QVideoFrame::unmap()
*/
int QVideoFrame::bytesPerLine() const
{
- return d->bytesPerLine[0];
+ return d->mapData.bytesPerLine[0];
}
/*!
@@ -702,7 +692,7 @@ int QVideoFrame::bytesPerLine() const
int QVideoFrame::bytesPerLine(int plane) const
{
- return plane >= 0 && plane < d->planeCount ? d->bytesPerLine[plane] : 0;
+ return plane >= 0 && plane < d->mapData.nPlanes ? d->mapData.bytesPerLine[plane] : 0;
}
/*!
@@ -718,7 +708,7 @@ int QVideoFrame::bytesPerLine(int plane) const
*/
uchar *QVideoFrame::bits()
{
- return d->data[0];
+ return d->mapData.data[0];
}
/*!
@@ -735,7 +725,7 @@ uchar *QVideoFrame::bits()
*/
uchar *QVideoFrame::bits(int plane)
{
- return plane >= 0 && plane < d->planeCount ? d->data[plane] : nullptr;
+ return plane >= 0 && plane < d->mapData.nPlanes ? d->mapData.data[plane] : nullptr;
}
/*!
@@ -750,7 +740,7 @@ uchar *QVideoFrame::bits(int plane)
*/
const uchar *QVideoFrame::bits() const
{
- return d->data[0];
+ return d->mapData.data[0];
}
/*!
@@ -766,7 +756,7 @@ const uchar *QVideoFrame::bits() const
*/
const uchar *QVideoFrame::bits(int plane) const
{
- return plane >= 0 && plane < d->planeCount ? d->data[plane] : nullptr;
+ return plane >= 0 && plane < d->mapData.nPlanes ? d->mapData.data[plane] : nullptr;
}
/*!
@@ -778,7 +768,7 @@ const uchar *QVideoFrame::bits(int plane) const
*/
int QVideoFrame::mappedBytes() const
{
- return d->mappedBytes;
+ return d->mapData.nBytes;
}
/*!
@@ -792,7 +782,7 @@ int QVideoFrame::mappedBytes() const
int QVideoFrame::planeCount() const
{
- return d->planeCount;
+ return d->mapData.nPlanes;
}
/*!
diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp
index 27cea76ad..3c6472482 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.cpp
+++ b/src/plugins/android/src/common/qandroidvideooutput.cpp
@@ -103,33 +103,31 @@ public:
virtual ~AndroidTextureVideoBuffer() {}
- MapMode mapMode() const { return m_mapMode; }
+ MapMode mapMode() const override { return m_mapMode; }
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ MapData map(MapMode mode) override
{
+ MapData mapData;
if (m_mapMode == NotMapped && mode == ReadOnly && updateFrame()) {
m_mapMode = mode;
m_image = m_output->m_fbo->toImage();
- if (numBytes)
- *numBytes = static_cast<int>(m_image.sizeInBytes());
-
- if (bytesPerLine)
- *bytesPerLine = m_image.bytesPerLine();
-
- return m_image.bits();
- } else {
- return 0;
+ mapData.nBytes = static_cast<int>(m_image.sizeInBytes());
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = m_image.bytesPerLine();
+ mapData.data[0] = m_image.bits();
}
+
+ return mapData;
}
- void unmap()
+ void unmap() override
{
m_image = QImage();
m_mapMode = NotMapped;
}
- QVariant handle() const
+ QVariant handle() const override
{
AndroidTextureVideoBuffer *that = const_cast<AndroidTextureVideoBuffer*>(this);
if (!that->updateFrame())
diff --git a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm
index 98cbf3df4..b77aa21ec 100644
--- a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm
+++ b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm
@@ -55,16 +55,16 @@
QT_USE_NAMESPACE
-class CVImageVideoBuffer : public QAbstractPlanarVideoBuffer
+class CVImageVideoBuffer : public QAbstractVideoBuffer
{
public:
CVImageVideoBuffer(CVImageBufferRef buffer, AVFCameraRendererControl *renderer)
#ifndef Q_OS_IOS
- : QAbstractPlanarVideoBuffer(NoHandle)
+ : QAbstractVideoBuffer(NoHandle)
#else
- : QAbstractPlanarVideoBuffer(renderer->supportsTextures()
- && CVPixelBufferGetPixelFormatType(buffer) == kCVPixelFormatType_32BGRA
- ? GLTextureHandle : NoHandle)
+ : QAbstractVideoBuffer(renderer->supportsTextures()
+ && CVPixelBufferGetPixelFormatType(buffer) == kCVPixelFormatType_32BGRA
+ ? GLTextureHandle : NoHandle)
, m_texture(nullptr)
, m_renderer(renderer)
#endif
@@ -89,16 +89,19 @@ public:
MapMode mapMode() const { return m_mode; }
- int map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
+ MapData map(QAbstractVideoBuffer::MapMode mode)
{
+ MapData mapData;
+
// We only support RGBA or NV12 (or Apple's version of NV12),
// they are either 0 planes or 2.
- const size_t nPlanes = CVPixelBufferGetPlaneCount(m_buffer);
- Q_ASSERT(nPlanes <= 2);
+ mapData.nPlanes = CVPixelBufferGetPlaneCount(m_buffer);
+ Q_ASSERT(mapData.nPlanes <= 2);
- if (!nPlanes) {
- data[0] = map(mode, numBytes, bytesPerLine);
- return data[0] ? 1 : 0;
+ if (!mapData.nPlanes) {
+ mapData.data[0] = map(mode, &mapData.nBytes, &mapData.bytesPerLine[0]);
+ mapData.nPlanes = mapData.data[0] ? 1 : 0;
+ return mapData;
}
// For a bi-planar format we have to set the parameters correctly:
@@ -107,27 +110,22 @@ public:
? kCVPixelBufferLock_ReadOnly
: 0);
- if (numBytes)
- *numBytes = CVPixelBufferGetDataSize(m_buffer);
+ mapData.nBytes = CVPixelBufferGetDataSize(m_buffer);
- if (bytesPerLine) {
- // At the moment we handle only bi-planar format.
- bytesPerLine[0] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 0);
- bytesPerLine[1] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 1);
- }
+ // At the moment we handle only bi-planar format.
+ mapData.bytesPerLine[0] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 0);
+ mapData.bytesPerLine[1] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 1);
- if (data) {
- data[0] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 0));
- data[1] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 1));
- }
+ mapData.data[0] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 0));
+ mapData.data[1] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 1));
m_mode = mode;
}
- return nPlanes;
+ return mapData;
}
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ uchar *map(MapMode mode, qsizetype *numBytes, int *bytesPerLine)
{
if (mode != NotMapped && m_mode == NotMapped) {
CVPixelBufferLockBaseAddress(m_buffer, mode == QAbstractVideoBuffer::ReadOnly
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
index 726dc5193..6e5b6a15e 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
@@ -71,7 +71,7 @@ public:
}
MapMode mapMode() const { return NotMapped; }
- uchar *map(MapMode, int*, int*) { return 0; }
+ MapData map(MapMode mode) override { return {}; }
void unmap() {}
QVariant handle() const
diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp
index 964504e48..51f8b1a39 100644
--- a/src/plugins/common/evr/evrd3dpresentengine.cpp
+++ b/src/plugins/common/evr/evrd3dpresentengine.cpp
@@ -90,7 +90,7 @@ public:
QVariant handle() const override;
MapMode mapMode() const override { return m_mapMode; }
- uchar *map(MapMode, int*, int*) override;
+ MapData map(MapMode mode) override;
void unmap() override;
private:
@@ -101,28 +101,27 @@ private:
mutable unsigned int m_textureId = 0;
};
-uchar *IMFSampleVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+IMFSampleVideoBuffer::MapData IMFSampleVideoBuffer::map(MapMode mode)
{
if (!m_surface || m_mapMode != NotMapped)
- return 0;
+ return {};
D3DSURFACE_DESC desc;
if (FAILED(m_surface->GetDesc(&desc)))
- return 0;
+ return {};
D3DLOCKED_RECT rect;
if (FAILED(m_surface->LockRect(&rect, NULL, mode == ReadOnly ? D3DLOCK_READONLY : 0)))
- return 0;
+ return {};
m_mapMode = mode;
- if (numBytes)
- *numBytes = (int)(rect.Pitch * desc.Height);
-
- if (bytesPerLine)
- *bytesPerLine = (int)rect.Pitch;
-
- return reinterpret_cast<uchar *>(rect.pBits);
+ MapData mapData;
+ mapData.nBytes = (int)(rect.Pitch * desc.Height);
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = (int)rect.Pitch;
+ mapData.data[0] = reinterpret_cast<uchar *>(rect.pBits);
+ return mapData;
}
void IMFSampleVideoBuffer::unmap()
diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
index 3b5715157..68cb47c3c 100644
--- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
@@ -154,15 +154,8 @@ public:
MapMode mapMode() const {
return QAbstractVideoBuffer::ReadWrite;
}
- void unmap() {
-
- }
- uchar *map(MapMode mode, int * numBytes, int * bytesPerLine) {
- Q_UNUSED(mode);
- Q_UNUSED(numBytes);
- Q_UNUSED(bytesPerLine);
- return 0;
- }
+ void unmap() {}
+ MapData map(MapMode mode) override { return {}; }
QVariant handle() const {
if (!m_handle) {
const_cast<QnxTextureBuffer*>(this)->m_handle = m_windowGrabber->getNextTextureId();
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 7b121255f..212533009 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -74,29 +74,27 @@ namespace
m_buffer->Release();
}
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ MapData map(MapMode mode) override
{
+ MapData mapData;
if (m_mapMode == NotMapped && mode != NotMapped) {
BYTE *bytes;
DWORD length;
HRESULT hr = m_buffer->Lock(&bytes, NULL, &length);
if (SUCCEEDED(hr)) {
- if (numBytes)
- *numBytes = int(length);
-
- if (bytesPerLine)
- *bytesPerLine = m_bytesPerLine;
-
+ mapData.nBytes = qsizetype(length);
+ mapData.nPlanes = 1;
+ mapData.bytesPerLine[0] = m_bytesPerLine;
+ mapData.data[0] = reinterpret_cast<uchar *>(bytes);
m_mapMode = mode;
- return reinterpret_cast<uchar *>(bytes);
} else {
qWarning("Faild to lock mf buffer!");
}
}
- return 0;
+ return mapData;
}
- void unmap()
+ void unmap() override
{
if (m_mapMode == NotMapped)
return;
@@ -104,7 +102,7 @@ namespace
m_buffer->Unlock();
}
- MapMode mapMode() const
+ MapMode mapMode() const override
{
return m_mapMode;
}
diff --git a/tests/auto/unit/qabstractvideobuffer/tst_qabstractvideobuffer.cpp b/tests/auto/unit/qabstractvideobuffer/tst_qabstractvideobuffer.cpp
index 146b26d30..e11fd6ac0 100644
--- a/tests/auto/unit/qabstractvideobuffer/tst_qabstractvideobuffer.cpp
+++ b/tests/auto/unit/qabstractvideobuffer/tst_qabstractvideobuffer.cpp
@@ -67,7 +67,7 @@ public:
[[nodiscard]] MapMode mapMode() const override { return QAbstractVideoBuffer::ReadWrite; }
- uchar *map(MapMode, int *, int *) override { return nullptr; }
+ MapData map(MapMode) override { return {}; }
void unmap() override {}
};
diff --git a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
index aea3e0e61..14f9309db 100644
--- a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
+++ b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
@@ -101,7 +101,7 @@ public:
[[nodiscard]] QVariant handle() const override { return m_textureId; }
- uchar *map(MapMode, int *, int *) override { return nullptr; }
+ MapData map(MapMode) override { return {}; }
void unmap() override {}
[[nodiscard]] MapMode mapMode() const override { return NotMapped; }
@@ -118,7 +118,7 @@ public:
: QAbstractVideoBuffer(UserHandle)
{}
- uchar *map(MapMode, int *, int *) override { return nullptr; }
+ MapData map(MapMode) override { return {}; }
void unmap() override {}
[[nodiscard]] MapMode mapMode() const override { return NotMapped; }
};
diff --git a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
index 6fcae820b..1eac0bed2 100644
--- a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
+++ b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
@@ -96,42 +96,44 @@ private slots:
Q_DECLARE_METATYPE(QImage::Format)
-class QtTestVideoBuffer : public QObject, public QAbstractVideoBuffer
+class QtTestDummyVideoBuffer : public QObject, public QAbstractVideoBuffer
{
Q_OBJECT
public:
- QtTestVideoBuffer()
+ QtTestDummyVideoBuffer()
: QAbstractVideoBuffer(NoHandle) {}
- explicit QtTestVideoBuffer(QAbstractVideoBuffer::HandleType type)
+ explicit QtTestDummyVideoBuffer(QAbstractVideoBuffer::HandleType type)
: QAbstractVideoBuffer(type) {}
[[nodiscard]] MapMode mapMode() const override { return NotMapped; }
- uchar *map(MapMode, int *, int *) override { return nullptr; }
+ MapData map(MapMode) override { return {}; }
void unmap() override {}
};
-class QtTestPlanarVideoBuffer : public QAbstractPlanarVideoBuffer
+class QtTestVideoBuffer : public QAbstractVideoBuffer
{
public:
- QtTestPlanarVideoBuffer()
- : QAbstractPlanarVideoBuffer(NoHandle)
+ QtTestVideoBuffer()
+ : QAbstractVideoBuffer(NoHandle)
{}
- explicit QtTestPlanarVideoBuffer(QAbstractVideoBuffer::HandleType type)
- : QAbstractPlanarVideoBuffer(type)
+ explicit QtTestVideoBuffer(QAbstractVideoBuffer::HandleType type)
+ : QAbstractVideoBuffer(type)
{}
[[nodiscard]] MapMode mapMode() const override { return m_mapMode; }
- int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) override {
+ MapData map(MapMode mode) override
+ {
m_mapMode = mode;
- if (numBytes)
- *numBytes = m_numBytes;
+ MapData mapData;
+ mapData.nBytes = m_numBytes;
+ mapData.nPlanes = m_planeCount;
for (int i = 0; i < m_planeCount; ++i) {
- data[i] = m_data[i];
- bytesPerLine[i] = m_bytesPerLine[i];
+ mapData.data[i] = m_data[i];
+ mapData.bytesPerLine[i] = m_bytesPerLine[i];
}
- return m_planeCount;
+ return mapData;
}
void unmap() override { m_mapMode = NotMapped; }
@@ -270,7 +272,7 @@ void tst_QVideoFrame::createFromBuffer()
QFETCH(QSize, size);
QFETCH(QVideoFrame::PixelFormat, pixelFormat);
- QVideoFrame frame(new QtTestVideoBuffer(handleType), size, pixelFormat);
+ QVideoFrame frame(new QtTestDummyVideoBuffer(handleType), size, pixelFormat);
QVERIFY(frame.isValid());
QCOMPARE(frame.handleType(), handleType);
@@ -386,7 +388,7 @@ void tst_QVideoFrame::createNull()
void tst_QVideoFrame::destructor()
{
- QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer;
+ QPointer<QtTestDummyVideoBuffer> buffer = new QtTestDummyVideoBuffer;
{
QVideoFrame frame(buffer, QSize(4, 1), QVideoFrame::Format_ARGB32);
@@ -443,7 +445,7 @@ void tst_QVideoFrame::copy()
QFETCH(qint64, startTime);
QFETCH(qint64, endTime);
- QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer(handleType);
+ QPointer<QtTestDummyVideoBuffer> buffer = new QtTestDummyVideoBuffer(handleType);
{
QVideoFrame frame(buffer, size, pixelFormat);
@@ -532,7 +534,7 @@ void tst_QVideoFrame::assign()
QFETCH(qint64, startTime);
QFETCH(qint64, endTime);
- QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer(handleType);
+ QPointer<QtTestDummyVideoBuffer> buffer = new QtTestDummyVideoBuffer(handleType);
QVideoFrame frame;
{
@@ -734,7 +736,7 @@ void tst_QVideoFrame::mapPlanes_data()
static uchar bufferData[1024];
- QtTestPlanarVideoBuffer *planarBuffer = new QtTestPlanarVideoBuffer;
+ QtTestVideoBuffer *planarBuffer = new QtTestVideoBuffer;
planarBuffer->m_data[0] = bufferData;
planarBuffer->m_data[1] = bufferData + 512;
planarBuffer->m_data[2] = bufferData + 765;