Fixed mapping video frames in SG nodes

Since it's possible to map video frame in R/O mode multiple times
it's always necessary to map it before accessing frame data.

Change-Id: I13f58085a0b19dba772e0b75c64d9f07d1ac2a58
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
Dmytro Poplavskiy
2012-01-20 14:30:03 +10:00
committed by Qt by Nokia
parent 48f714037e
commit a465e37bd6
2 changed files with 32 additions and 36 deletions

View File

@@ -225,13 +225,8 @@ void QSGVideoMaterial_YUV420::bind()
QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
QMutexLocker lock(&m_frameMutex);
if (m_frame.isValid() && m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
bool wasMapped = m_frame.isMapped();
if (!wasMapped)
m_frame.map(QAbstractVideoBuffer::ReadOnly);
if (m_frame.isMapped()) {
if (m_frame.isValid()) {
if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
int fw = m_frame.width();
int fh = m_frame.height();
@@ -260,8 +255,7 @@ void QSGVideoMaterial_YUV420::bind()
functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
bindTexture(m_textureIds[0], fw, fh, bits);
if (!wasMapped)
m_frame.unmap();
m_frame.unmap();
}
m_frame = QVideoFrame();

View File

@@ -197,34 +197,36 @@ public:
QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
QMutexLocker lock(&m_frameMutex);
if (m_frame.isValid() && m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
if (m_textureSize != m_frame.size()) {
if (!m_textureSize.isEmpty())
glDeleteTextures(1, &m_textureId);
glGenTextures(1, &m_textureId);
m_textureSize = m_frame.size();
if (m_frame.isValid()) {
if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
if (m_textureSize != m_frame.size()) {
if (!m_textureSize.isEmpty())
glDeleteTextures(1, &m_textureId);
glGenTextures(1, &m_textureId);
m_textureSize = m_frame.size();
}
GLint dataType = GL_UNSIGNED_BYTE;
GLint dataFormat = GL_RGBA;
if (m_frame.pixelFormat() == QVideoFrame::Format_RGB565) {
dataType = GL_UNSIGNED_SHORT_5_6_5;
dataFormat = GL_RGB;
}
functions->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexImage2D(GL_TEXTURE_2D, 0, dataFormat,
m_textureSize.width(), m_textureSize.height(),
0, dataFormat, dataType, m_frame.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_frame.unmap();
}
GLint dataType = GL_UNSIGNED_BYTE;
GLint dataFormat = GL_RGBA;
if (m_frame.pixelFormat() == QVideoFrame::Format_RGB565) {
dataType = GL_UNSIGNED_SHORT_5_6_5;
dataFormat = GL_RGB;
}
functions->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexImage2D(GL_TEXTURE_2D, 0, dataFormat,
m_textureSize.width(), m_textureSize.height(),
0, dataFormat, dataType, m_frame.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_frame.unmap();
m_frame = QVideoFrame();
} else {
functions->glActiveTexture(GL_TEXTURE0);