CVMetalTextureCacheCreateTextureFromImage报错-6660问题排查求助
解决CVMetalTextureCacheCreateTextureFromImage报错-6660的问题
首先,错误码-6660对应的是参数不匹配或像素格式兼容问题,结合你的代码来看,主要是这几个核心问题导致的:
问题拆解
- 硬编码宽高不匹配:你在
CVMetalTextureCacheCreateTextureFromImage里固定写死了1920, 1080,但函数本身接收外部传入的width和height参数。如果调用时传入的尺寸不是1920x1080,就会和CVPixelBuffer的实际尺寸冲突,直接触发错误。 - 资源未正确释放:创建的
CVMetalTextureCacheRef和CVPixelBufferRef在函数失败或结束时没有释放,不仅会造成内存泄漏,还可能干扰后续的纹理缓存操作。 - 释放回调的不确定性:你传入了
releaseCallback但未给出具体实现,如果这个回调定义错误,会导致CVPixelBuffer释放时出现异常,间接引发纹理创建失败。
修正后的代码
id<MTLTexture> makeTextureWithBytes(id<MTLDevice> mtl_device, int width, int height, void *baseAddress, int bytesPerRow) { CVMetalTextureCacheRef textureCache = NULL; CVReturn status = CVMetalTextureCacheCreate(kCFAllocatorDefault, nullptr, mtl_device, nullptr, &textureCache); if(status != kCVReturnSuccess || textureCache == NULL) { NSLog(@"Failed to create CVMetalTextureCache"); return nullptr; } NSDictionary* cvBufferProperties = @{ (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey : @YES, // 若不需要OpenGL兼容可移除该配置,减少不必要的开销 // (__bridge NSString*)kCVPixelBufferOpenGLCompatibilityKey : @YES, }; CVPixelBufferRef pxbuffer = NULL; // 若无自定义释放需求,直接传NULL替代releaseCallback status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, baseAddress, bytesPerRow, NULL, NULL, (__bridge CFDictionaryRef)cvBufferProperties, &pxbuffer); if(status != kCVReturnSuccess || pxbuffer == NULL) { NSLog(@"Failed to create CVPixelBuffer, status: %d", status); CFRelease(textureCache); return nullptr; } CVMetalTextureRef cvTexture = NULL; // 使用传入的动态宽高,替代硬编码值 status = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pxbuffer, nullptr, MTLPixelFormatBGRA8Unorm, width, height, 0, &cvTexture); if(status != kCVReturnSuccess || cvTexture == NULL) { NSLog(@"CVMetalTextureCacheCreateTextureFromImage failed, status: %d", status); CFRelease(pxbuffer); CFRelease(textureCache); return nullptr; } id<MTLTexture> metalTexture = CVMetalTextureGetTexture(cvTexture); // 注意:MTLTexture依赖CVMetalTextureRef的生命周期,不能立即释放cvTexture // 可通过关联对象或自定义结构体管理两者生命周期,避免纹理失效 CFRelease(pxbuffer); CFRelease(textureCache); // CFRelease(cvTexture); // 若需保留metalTexture,需延后释放cvTexture return metalTexture; }
额外注意点
- 纹理生命周期管理:
CVMetalTextureGetTexture返回的MTLTexture依赖CVMetalTextureRef存在,因此不能在返回metalTexture前释放cvTexture,否则纹理会直接失效。可以考虑将cvTexture作为关联对象绑定到metalTexture,或让调用者同时持有两者并负责释放。 - 字节行对齐:确保
bytesPerRow符合Metal的对齐要求(通常是宽度×像素字节数,且对齐到16字节倍数),行字节数不对齐也可能触发格式错误。 - 像素数据一致性:确认
baseAddress中的数据确实是32位BGRA格式,即使格式参数匹配,数据格式不符也会导致纹理异常或创建失败。
内容的提问来源于stack exchange,提问作者StNickolay
相关产品推荐
相关产品推荐

