Support per-plane strides and data offsets in QVideoFrame.
Since just adding a new virtual isn't binary compatible add a new derivative type with a virtual member and connect it up through a virtual in the private class. [ChangeLog] Support for per-plane strides and data offsets in QVideoFrame. Task-number: QTBUG-38345 Change-Id: I1974c2b0b454d130e17971ce549031259d61f9cd Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
committed by
Yoann Lopes
parent
ab379c3da2
commit
1a3ae99441
@@ -56,6 +56,15 @@ 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
|
||||
@@ -130,6 +139,7 @@ QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, Hand
|
||||
: d_ptr(&dd)
|
||||
, m_type(type)
|
||||
{
|
||||
d_ptr->q_ptr = this;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -199,6 +209,44 @@ QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
|
||||
\sa unmap(), mapMode()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
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
|
||||
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 the number of planes in the mapped video data. For each plane the line stride of that
|
||||
plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
|
||||
\a data. The accumulative size of the mapped data is returned in \a numBytes.
|
||||
|
||||
Not all buffer implementations will map more than the first plane, if this returns a single
|
||||
plane for a planar format the additional planes will have to be calculated from the line stride
|
||||
of the first plane and the frame height. Mapping a buffer with QVideoFrame will do this for
|
||||
you.
|
||||
|
||||
To implement this function create a derivative of QAbstractPlanarVideoBuffer and implement
|
||||
its map function instance instead.
|
||||
|
||||
\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);
|
||||
} else {
|
||||
data[0] = map(mode, numBytes, bytesPerLine);
|
||||
|
||||
return data[0] ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QAbstractVideoBuffer::unmap()
|
||||
|
||||
@@ -222,6 +270,90 @@ 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];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn int QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
|
||||
|
||||
Maps the contents of a video buffer to memory.
|
||||
|
||||
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 the number of planes in the mapped video data. For each plane the line stride of that
|
||||
plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
|
||||
\a data. The accumulative size of the mapped data is returned in \a numBytes.
|
||||
|
||||
\sa QAbstractVideoBuffer::map(), QAbstractVideoBuffer::unmap(), QAbstractVideoBuffer::mapMode()
|
||||
*/
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::HandleType type)
|
||||
{
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
virtual MapMode mapMode() const = 0;
|
||||
|
||||
virtual uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) = 0;
|
||||
int mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]);
|
||||
virtual void unmap() = 0;
|
||||
|
||||
virtual QVariant handle() const;
|
||||
@@ -100,6 +101,23 @@ private:
|
||||
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);
|
||||
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);
|
||||
|
||||
@@ -66,10 +66,31 @@ class QAbstractVideoBufferPrivate
|
||||
{
|
||||
public:
|
||||
QAbstractVideoBufferPrivate()
|
||||
: q_ptr(0)
|
||||
{}
|
||||
|
||||
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]);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PUBLIC(QAbstractPlanarVideoBuffer)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -71,28 +71,30 @@ public:
|
||||
QVideoFramePrivate()
|
||||
: startTime(-1)
|
||||
, endTime(-1)
|
||||
, data(0)
|
||||
, mappedBytes(0)
|
||||
, bytesPerLine(0)
|
||||
, planeCount(0)
|
||||
, pixelFormat(QVideoFrame::Format_Invalid)
|
||||
, fieldType(QVideoFrame::ProgressiveFrame)
|
||||
, buffer(0)
|
||||
, mappedCount(0)
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(bytesPerLine, 0, sizeof(bytesPerLine));
|
||||
}
|
||||
|
||||
QVideoFramePrivate(const QSize &size, QVideoFrame::PixelFormat format)
|
||||
: size(size)
|
||||
, startTime(-1)
|
||||
, endTime(-1)
|
||||
, data(0)
|
||||
, mappedBytes(0)
|
||||
, bytesPerLine(0)
|
||||
, planeCount(0)
|
||||
, pixelFormat(format)
|
||||
, fieldType(QVideoFrame::ProgressiveFrame)
|
||||
, buffer(0)
|
||||
, mappedCount(0)
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(bytesPerLine, 0, sizeof(bytesPerLine));
|
||||
}
|
||||
|
||||
~QVideoFramePrivate()
|
||||
@@ -104,9 +106,10 @@ public:
|
||||
QSize size;
|
||||
qint64 startTime;
|
||||
qint64 endTime;
|
||||
uchar *data;
|
||||
uchar *data[4];
|
||||
int bytesPerLine[4];
|
||||
int mappedBytes;
|
||||
int bytesPerLine;
|
||||
int planeCount;
|
||||
QVideoFrame::PixelFormat pixelFormat;
|
||||
QVideoFrame::FieldType fieldType;
|
||||
QAbstractVideoBuffer *buffer;
|
||||
@@ -564,18 +567,88 @@ bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(d->data == 0);
|
||||
Q_ASSERT(d->bytesPerLine == 0);
|
||||
Q_ASSERT(d->data[0] == 0);
|
||||
Q_ASSERT(d->bytesPerLine[0] == 0);
|
||||
Q_ASSERT(d->planeCount == 0);
|
||||
Q_ASSERT(d->mappedBytes == 0);
|
||||
|
||||
d->data = d->buffer->map(mode, &d->mappedBytes, &d->bytesPerLine);
|
||||
d->planeCount = d->buffer->mapPlanes(mode, &d->mappedBytes, d->bytesPerLine, d->data);
|
||||
if (d->planeCount == 0)
|
||||
return false;
|
||||
|
||||
if (d->data) {
|
||||
d->mappedCount++;
|
||||
return true;
|
||||
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_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_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 uvStride = (d->mappedBytes - (yStride * height)) / height;
|
||||
|
||||
// Three planes, the second and third vertically and horizontally 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 * height / 2);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
d->mappedCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -604,8 +677,9 @@ void QVideoFrame::unmap()
|
||||
|
||||
if (d->mappedCount == 0) {
|
||||
d->mappedBytes = 0;
|
||||
d->bytesPerLine = 0;
|
||||
d->data = 0;
|
||||
d->planeCount = 0;
|
||||
memset(d->bytesPerLine, 0, sizeof(d->bytesPerLine));
|
||||
memset(d->data, 0, sizeof(d->data));
|
||||
|
||||
d->buffer->unmap();
|
||||
}
|
||||
@@ -623,7 +697,21 @@ void QVideoFrame::unmap()
|
||||
*/
|
||||
int QVideoFrame::bytesPerLine() const
|
||||
{
|
||||
return d->bytesPerLine;
|
||||
return d->bytesPerLine[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of bytes in a scan line of a \a plane.
|
||||
|
||||
This value is only valid while the frame data is \l {map()}{mapped}.
|
||||
|
||||
\sa bits(), map(), mappedBytes(), planeCount()
|
||||
\since 5.4
|
||||
*/
|
||||
|
||||
int QVideoFrame::bytesPerLine(int plane) const
|
||||
{
|
||||
return plane >= 0 && plane < d->planeCount ? d->bytesPerLine[plane] : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -639,7 +727,24 @@ int QVideoFrame::bytesPerLine() const
|
||||
*/
|
||||
uchar *QVideoFrame::bits()
|
||||
{
|
||||
return d->data;
|
||||
return d->data[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a pointer to the start of the frame data buffer for a \a plane.
|
||||
|
||||
This value is only valid while the frame data is \l {map()}{mapped}.
|
||||
|
||||
Changes made to data accessed via this pointer (when mapped with write access)
|
||||
are only guaranteed to have been persisted when unmap() is called and when the
|
||||
buffer has been mapped for writing.
|
||||
|
||||
\sa map(), mappedBytes(), bytesPerLine(), planeCount()
|
||||
\since 5.4
|
||||
*/
|
||||
uchar *QVideoFrame::bits(int plane)
|
||||
{
|
||||
return plane >= 0 && plane < d->planeCount ? d->data[plane] : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -654,7 +759,23 @@ uchar *QVideoFrame::bits()
|
||||
*/
|
||||
const uchar *QVideoFrame::bits() const
|
||||
{
|
||||
return d->data;
|
||||
return d->data[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a pointer to the start of the frame data buffer for a \a plane.
|
||||
|
||||
This value is only valid while the frame data is \l {map()}{mapped}.
|
||||
|
||||
If the buffer was not mapped with read access, the contents of this
|
||||
buffer will initially be uninitialized.
|
||||
|
||||
\sa map(), mappedBytes(), bytesPerLine(), planeCount()
|
||||
\since 5.4
|
||||
*/
|
||||
const uchar *QVideoFrame::bits(int plane) const
|
||||
{
|
||||
return plane >= 0 && plane < d->planeCount ? d->data[plane] : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -669,6 +790,20 @@ int QVideoFrame::mappedBytes() const
|
||||
return d->mappedBytes;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the number of planes in the video frame.
|
||||
|
||||
This value is only valid while the frame data is \l {map()}{mapped}.
|
||||
|
||||
\sa map()
|
||||
\since 5.4
|
||||
*/
|
||||
|
||||
int QVideoFrame::planeCount() const
|
||||
{
|
||||
return d->planeCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a type specific handle to a video frame's buffer.
|
||||
|
||||
@@ -852,9 +987,6 @@ QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format)
|
||||
return QImage::Format_Invalid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
|
||||
{
|
||||
|
||||
@@ -139,10 +139,14 @@ public:
|
||||
void unmap();
|
||||
|
||||
int bytesPerLine() const;
|
||||
int bytesPerLine(int plane) const;
|
||||
|
||||
uchar *bits();
|
||||
uchar *bits(int plane);
|
||||
const uchar *bits() const;
|
||||
const uchar *bits(int plane) const;
|
||||
int mappedBytes() const;
|
||||
int planeCount() const;
|
||||
|
||||
QVariant handle() const;
|
||||
|
||||
|
||||
@@ -257,33 +257,23 @@ void QSGVideoMaterial_YUV420::bind()
|
||||
m_textureSize = m_frame.size();
|
||||
}
|
||||
|
||||
const uchar *bits = m_frame.bits();
|
||||
int yStride = m_frame.bytesPerLine();
|
||||
// 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.
|
||||
int uvStride = (m_frame.mappedBytes() - yStride * fh) / fh;
|
||||
int offsetU = yStride * fh;
|
||||
int offsetV = yStride * fh + uvStride * fh / 2;
|
||||
const int y = 0;
|
||||
const int u = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 1 : 2;
|
||||
const int v = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 2 : 1;
|
||||
|
||||
m_yWidth = qreal(fw) / yStride;
|
||||
m_uvWidth = qreal(fw) / (2 * uvStride);
|
||||
|
||||
if (m_frame.pixelFormat() == QVideoFrame::Format_YV12)
|
||||
qSwap(offsetU, offsetV);
|
||||
m_yWidth = qreal(fw) / m_frame.bytesPerLine(y);
|
||||
m_uvWidth = qreal(fw) / (2 * m_frame.bytesPerLine(u));
|
||||
|
||||
GLint previousAlignment;
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
functions->glActiveTexture(GL_TEXTURE1);
|
||||
bindTexture(m_textureIds[1], uvStride, fh / 2, bits + offsetU);
|
||||
bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), fh / 2, m_frame.bits(u));
|
||||
functions->glActiveTexture(GL_TEXTURE2);
|
||||
bindTexture(m_textureIds[2], uvStride, fh / 2, bits + offsetV);
|
||||
bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), fh / 2, m_frame.bits(v));
|
||||
functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
|
||||
bindTexture(m_textureIds[0], yStride, fh, bits);
|
||||
bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y));
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment);
|
||||
|
||||
@@ -350,7 +340,6 @@ void QSGVideoMaterialShader_YUV420::updateState(const RenderState &state,
|
||||
mat->m_opacity = state.opacity();
|
||||
program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity));
|
||||
}
|
||||
|
||||
if (state.isMatrixDirty())
|
||||
program()->setUniformValue(m_id_matrix, state.combinedMatrix());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user