summaryrefslogtreecommitdiffstats
path: root/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2020-05-28 17:35:16 +0200
committerVal Doroshchuk <valentyn.doroshchuk@qt.io>2020-06-10 10:06:22 +0200
commit22ae5eec6314b59c8a969b743a9c05fb184cc9b2 (patch)
tree898464db0d98f53ff7f10dd378c2dc4ed842cfd1 /src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
parentb5a55492a63cb2cda75d6f980acb7fc5ae8dfc22 (diff)
Introduce QAbstractVideoBuffer::MTLTextureHandle
Added MTLTextureHandle to render metal textures. Is used by default if rhi is enabled for metal backend. Also fixed the frame renderer to create new opengl context and use provided one from the video surface as a share context. To remember, when the quick item is created and updatePaintNode is called, current gl context is set to the video surface as a property. When the frame renderer is ready, it extracts the gl context and uses it as a share one. Task-number: QTBUG-78678 Change-Id: I51ce666ca7c2adc10dd2c1d1dfed99cc9f596e2b Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm')
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
index 2cdf1cac9..f81412d65 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
@@ -72,13 +72,14 @@ AVFVideoFrameRenderer::~AVFVideoFrameRenderer()
#endif
[m_videoLayerRenderer release];
+ [m_metalDevice release];
delete m_fbo[0];
delete m_fbo[1];
delete m_offscreenSurface;
delete m_glContext;
}
-GLuint AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer)
+quint64 AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer)
{
//Is layer valid
if (!layer)
@@ -100,6 +101,44 @@ GLuint AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer)
return fbo->texture();
}
+quint64 AVFVideoFrameRenderer::renderLayerToMTLTexture(AVPlayerLayer *layer)
+{
+ m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height);
+
+ if (!m_metalDevice)
+ m_metalDevice = MTLCreateSystemDefaultDevice();
+
+ if (!m_metalTexture) {
+ auto desc = [[MTLTextureDescriptor alloc] init];
+ desc.textureType = MTLTextureType2D;
+ desc.width = NSUInteger(m_targetSize.width());
+ desc.height = NSUInteger(m_targetSize.height());
+ desc.resourceOptions = MTLResourceStorageModePrivate;
+ desc.usage = MTLTextureUsageRenderTarget;
+ desc.pixelFormat = MTLPixelFormatRGBA8Unorm;
+
+ m_metalTexture = [m_metalDevice newTextureWithDescriptor: desc];
+ [desc release];
+ }
+
+ if (!m_videoLayerRenderer) {
+ m_videoLayerRenderer = [CARenderer rendererWithMTLTexture:m_metalTexture options:nil];
+ [m_videoLayerRenderer retain];
+ }
+
+ if (m_videoLayerRenderer.layer != layer) {
+ m_videoLayerRenderer.layer = layer;
+ m_videoLayerRenderer.bounds = layer.bounds;
+ }
+
+ [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL];
+ [m_videoLayerRenderer addUpdateRect:layer.bounds];
+ [m_videoLayerRenderer render];
+ [m_videoLayerRenderer endFrame];
+
+ return quint64(m_metalTexture);
+}
+
QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer)
{
//Is layer valid
@@ -131,8 +170,7 @@ QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *lay
: nullptr;
//Make sure we have an OpenGL context to make current
- if ((shareContext && shareContext != QOpenGLContext::currentContext())
- || (!QOpenGLContext::currentContext() && !m_glContext)) {
+ if (shareContext || (!QOpenGLContext::currentContext() && !m_glContext)) {
//Create Hidden QWindow surface to create context in this thread
delete m_offscreenSurface;