6#if !defined(Q_OS_DARWIN)
7#error "Configuration error"
13#include "private/qvideotexturehelper_p.h"
17#include <CoreVideo/CVMetalTexture.h>
18#include <CoreVideo/CVMetalTextureCache.h>
25#import <OpenGLES/EAGL.h>
27#import <Metal/Metal.h>
36static CVMetalTextureCacheRef &mtc(
void *&
cache) {
return reinterpret_cast<CVMetalTextureCacheRef &
>(
cache); }
38class VideoToolBoxTextureSet :
public TextureSet
41 ~VideoToolBoxTextureSet();
42 qint64 textureHandle(
int plane)
override;
45 CVMetalTextureRef cvMetalTexture[3] = {};
47#if defined(Q_OS_MACOS)
48 CVOpenGLTextureRef cvOpenGLTexture =
nullptr;
49#elif defined(Q_OS_IOS)
50 CVOpenGLESTextureRef cvOpenGLESTexture =
nullptr;
53 CVImageBufferRef m_buffer =
nullptr;
56VideoToolBoxTextureConverter::VideoToolBoxTextureConverter(
QRhi *rhi)
57 : TextureConverterBackend(rhi)
67 if (CVMetalTextureCacheCreate(
72 &mtc(cvMetalTextureCache)) != kCVReturnSuccess) {
73 qWarning() <<
"Metal texture cache creation failed";
82 auto nsGLPixelFormat = nsGLContext.pixelFormat.CGLPixelFormatObj;
85 if (CVOpenGLTextureCacheCreate(
88 reinterpret_cast<CGLContextObj
>(nsGLContext.CGLContextObj),
91 &cvOpenGLTextureCache)) {
92 qWarning() <<
"OpenGL texture cache creation failed";
98 if (CVOpenGLESTextureCacheCreate(
101 [EAGLContext currentContext],
103 &cvOpenGLESTextureCache)) {
104 qWarning() <<
"OpenGL texture cache creation failed";
114VideoToolBoxTextureConverter::~VideoToolBoxTextureConverter()
119void VideoToolBoxTextureConverter::freeTextureCaches()
121 if (cvMetalTextureCache)
122 CFRelease(cvMetalTextureCache);
123 cvMetalTextureCache =
nullptr;
124#if defined(Q_OS_MACOS)
125 if (cvOpenGLTextureCache)
126 CFRelease(cvOpenGLTextureCache);
127 cvOpenGLTextureCache =
nullptr;
128#elif defined(Q_OS_IOS)
129 if (cvOpenGLESTextureCache)
130 CFRelease(cvOpenGLESTextureCache);
131 cvOpenGLESTextureCache =
nullptr;
140 return MTLPixelFormatInvalid;
142 return MTLPixelFormatRGBA8Unorm;
144 return MTLPixelFormatBGRA8Unorm;
146 return MTLPixelFormatR8Unorm;
148 return MTLPixelFormatRG8Unorm;
150 return MTLPixelFormatR16Unorm;
152 return MTLPixelFormatRG16Unorm;
155 return MTLPixelFormatRGBA16Float;
157 return MTLPixelFormatRGBA32Float;
159 return MTLPixelFormatR16Float;
161 return MTLPixelFormatR32Float;
165TextureSet *VideoToolBoxTextureConverter::getTextures(AVFrame *
frame)
170 bool needsConversion =
false;
172 if (needsConversion) {
177 CVPixelBufferRef
buffer = (CVPixelBufferRef)
frame->data[3];
179 auto textureSet = std::make_unique<VideoToolBoxTextureSet>();
180 textureSet->m_buffer =
buffer;
181 textureSet->rhi = rhi;
182 CVPixelBufferRetain(
buffer);
185 int bufferPlanes = CVPixelBufferGetPlaneCount(
buffer);
189 for (
int plane = 0; plane < bufferPlanes; ++plane) {
196 auto ret = CVMetalTextureCacheCreateTextureFromImage(
198 mtc(cvMetalTextureCache),
203 &textureSet->cvMetalTexture[plane]);
205 if (
ret != kCVReturnSuccess)
214 CVOpenGLTextureCacheFlush(cvOpenGLTextureCache, 0);
216 const CVReturn cvret = CVOpenGLTextureCacheCreateTextureFromImage(
218 cvOpenGLTextureCache,
221 &textureSet->cvOpenGLTexture);
222 if (cvret != kCVReturnSuccess) {
223 qCWarning(qLcVideotoolbox) <<
"OpenGL texture creation failed" << cvret;
230 CVOpenGLESTextureCacheFlush(cvOpenGLESTextureCache, 0);
232 const CVReturn cvret = CVOpenGLESTextureCacheCreateTextureFromImage(
234 cvOpenGLESTextureCache,
239 CVPixelBufferGetWidth(
buffer),
240 CVPixelBufferGetHeight(
buffer),
244 &textureSet->cvOpenGLESTexture);
245 if (cvret != kCVReturnSuccess) {
246 qCWarning(qLcVideotoolbox) <<
"OpenGL ES texture creation failed" << cvret;
253 return textureSet.release();
256VideoToolBoxTextureSet::~VideoToolBoxTextureSet()
258 for (
int i = 0;
i < 4; ++
i)
259 if (cvMetalTexture[
i])
260 CFRelease(cvMetalTexture[
i]);
261#if defined(Q_OS_MACOS)
263 CVOpenGLTextureRelease(cvOpenGLTexture);
264#elif defined(Q_OS_IOS)
265 if (cvOpenGLESTexture)
266 CFRelease(cvOpenGLESTexture);
268 CVPixelBufferRelease(m_buffer);
271qint64 VideoToolBoxTextureSet::textureHandle(
int plane)
274 return cvMetalTexture[plane] ?
qint64(CVMetalTextureGetTexture(cvMetalTexture[plane])) : 0;
278 return CVOpenGLTextureGetName(cvOpenGLTexture);
281 return CVOpenGLESTextureGetName(cvOpenGLESTexture);
static MTLPixelFormat rhiTextureFormatToMetalFormat(QRhiTexture::Format f)
static QVideoFrameFormat::PixelFormat toQtPixelFormat(AVPixelFormat avPixelFormat, bool *needsConversion=nullptr)
Native interface to an NSOpenGLContext on \macos.
\variable QRhiGles2InitParams::format
Format
Specifies the texture format.
Implementation backend() const
const QRhiNativeHandles * nativeHandles()
QCache< int, Employee > cache
[0]
Combined button and popup list for selecting options.
const TextureDescription * textureDescription(QVideoFrameFormat::PixelFormat format)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLint GLsizei GLsizei height
#define GL_TEXTURE_RECTANGLE
QRhiTexture::Format textureFormat[maxPlanes]
int widthForPlane(int width, int plane) const
int heightForPlane(int height, int plane) const