7 #define LOC QString("VTBInterop: ")
11 if (Render->isOpenGLES() || Render->
IsEGL())
14 if (Render->hasExtension(
"GL_ARB_texture_rg"))
29 for (
auto type : vtb->second)
56 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Mismatched OpenGL contexts");
59 QSize surfacesize(
Frame->m_width,
Frame->m_height);
64 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Video texture size changed! %1x%2->%3x%4")
82 return reinterpret_cast<CVPixelBufferRef
>(
Frame->m_buffer);
85 std::vector<MythVideoTextureOpenGL*>
91 std::vector<MythVideoTextureOpenGL*> result;
94 CVPixelBufferRef buffer =
Verify(Context, ColourSpace,
Frame);
104 int planes = CVPixelBufferGetPlaneCount(buffer);
105 CVPixelBufferLockBaseAddress(buffer, kCVPixelBufferLock_ReadOnly);
115 for (
int plane = 0; plane < planes; ++plane)
117 int width = CVPixelBufferGetWidthOfPlane(buffer, plane);
118 int height = CVPixelBufferGetHeightOfPlane(buffer, plane);
119 QSize size(width, height);
128 result.push_back(texture);
132 if (result.size() !=
static_cast<uint>(planes))
133 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create all textures");
143 for (
int plane = 0; plane < planes; ++plane)
145 if (
static_cast<uint>(plane) >= result.size())
148 int width = CVPixelBufferGetWidthOfPlane(buffer, plane);
149 int height = CVPixelBufferGetHeightOfPlane(buffer, plane);
150 int bytes = CVPixelBufferGetBytesPerRowOfPlane(buffer, plane) / width;
151 void* buf = CVPixelBufferGetBaseAddressOfPlane(buffer, plane);
152 result[plane]->m_texture->bind();
153 if ((
bytes == 1) && buf)
155 m_openglContext->glTexImage2D(QOpenGLTexture::Target2D, 0, QOpenGLTexture::RGBA, width, height,
156 0, QOpenGLTexture::Red, QOpenGLTexture::UInt8, buf);
158 else if ((
bytes == 2) && buf)
160 m_openglContext->glTexImage2D(QOpenGLTexture::Target2D, 0, QOpenGLTexture::RGBA, width, height,
161 0, QOpenGLTexture::RG, QOpenGLTexture::UInt8, buf);
163 result[plane]->m_texture->release();
166 CVPixelBufferUnlockBaseAddress(buffer, kCVPixelBufferLock_ReadOnly);
179 std::vector<MythVideoTextureOpenGL*>
185 std::vector<MythVideoTextureOpenGL*> result;
188 CVPixelBufferRef buffer =
Verify(Context, ColourSpace,
Frame);
192 IOSurfaceRef surface = CVPixelBufferGetIOSurface(buffer);
195 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to retrieve IOSurface from CV buffer");
199 IOSurfaceID surfaceid = IOSurfaceGetID(surface);
204 bool needreferences =
false;
235 int planes = IOSurfaceGetPlaneCount(surface);
236 IOSurfaceLock(surface, kIOSurfaceLockReadOnly,
nullptr);
239 std::vector<QSize> sizes;
240 for (
int plane = 0; plane < planes; ++plane)
242 int width = IOSurfaceGetWidthOfPlane(surface, plane);
243 int height = IOSurfaceGetHeightOfPlane(surface, plane);
244 sizes.push_back(QSize(width, height));
252 IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly,
nullptr);
253 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unsupported frame format %1")
260 for (
uint plane = 0; plane < result.size(); ++plane)
268 GLenum format = (plane == 0) ? QOpenGLTexture::Red : QOpenGLTexture::RG;;
269 GLenum dataformat = (frameformat ==
FMT_NV12) ? QOpenGLTexture::UInt8 : QOpenGLTexture::UInt16;
271 CGLError
error = CGLTexImageIOSurface2D(
272 CGLGetCurrentContext(), QOpenGLTexture::TargetRectangle, format,
274 format, dataformat, surface, plane);
275 if (
error != kCGLNoError)
276 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"CGLTexImageIOSurface2D error %1").arg(
error));
280 IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly,
nullptr);
306 std::vector<MythVideoTextureOpenGL*> result;
318 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Reference frame error");