使用 CVMetalTextureCacheCreateTextureFromImage 在 Swift 中将 CMSampleBuffer 转换为 CVMetalTexture
Converting CMSampleBuffer to CVMetalTexture in Swift with CVMetalTextureCacheCreateTextureFromImage
我正在尝试建立一个简单的渲染相机输出到金属层管道,它在 Objective-C 中运行良好(有 MetalVideoCapture 示例应用程序),但似乎当我尝试将其转换为 swift 时,出现了一些格式异常。我的超简单捕获缓冲区看起来像这样(忽略缺乏清理...)
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
var error: CVReturn! = nil
let sourceImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let width = CVPixelBufferGetWidth(sourceImageBuffer!)
let height = CVPixelBufferGetHeight(sourceImageBuffer!)
var outTexture: CVMetalTextureRef? = nil
error = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache!, sourceImageBuffer!, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &outTexture!)
if error != nil {
print("Error! \(error)")
}
let videoTexture = CVMetalTextureGetTexture(outTexture!)
self.imageTexture = videoTexture!
}
其中 videoTextureCache var videoTextureCache: CVMetalTextureCache? = nil
但它给了我 Cannot invoke 'CVMetalTextureCacheCreateTextureFromImage' with an argument list of type '(CFAllocator!, CVMetalTextureCache, CVImageBuffer, nil, MTLPixelFormat, Int, Int, Int, inout CVMetalTextureRef)'
问题是,如果我将 outTexture 替换为 nil,它就会停止抛出错误,但显然这对我没有帮助。根据函数的参考,我需要 UnsafeMutablePointer?> 最后一个值。我不确定如何获得。
尽量提前分配你的textureCache,这里是我用的成员变量:
var _videoTextureCache : Unmanaged<CVMetalTextureCacheRef>?
然后我通过
在初始化方法中分配textureCache
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache)
其中 _context.device 是 MTLDevice。然后,在 captureOutput 方法中,我使用以下内容(注意,此处不包括错误检查)
var textureRef : Unmanaged<CVMetalTextureRef>?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache!.takeUnretainedValue(), imageBuffer, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &textureRef)
希望对您有所帮助!
更新@peacer212 对Swift 3.
的回答
您不再需要 Unmanaged
和 takeUnretainedValue
。所以代码应该是:
var textureCache: CVMetalTextureCache?
...
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache)
...
var textureRef : CVMetalTexture?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache!, imageBuffer, nil, .bgra8Unorm, width, height, 0, & textureRef)
我正在尝试建立一个简单的渲染相机输出到金属层管道,它在 Objective-C 中运行良好(有 MetalVideoCapture 示例应用程序),但似乎当我尝试将其转换为 swift 时,出现了一些格式异常。我的超简单捕获缓冲区看起来像这样(忽略缺乏清理...)
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
var error: CVReturn! = nil
let sourceImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let width = CVPixelBufferGetWidth(sourceImageBuffer!)
let height = CVPixelBufferGetHeight(sourceImageBuffer!)
var outTexture: CVMetalTextureRef? = nil
error = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache!, sourceImageBuffer!, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &outTexture!)
if error != nil {
print("Error! \(error)")
}
let videoTexture = CVMetalTextureGetTexture(outTexture!)
self.imageTexture = videoTexture!
}
其中 videoTextureCache var videoTextureCache: CVMetalTextureCache? = nil
但它给了我 Cannot invoke 'CVMetalTextureCacheCreateTextureFromImage' with an argument list of type '(CFAllocator!, CVMetalTextureCache, CVImageBuffer, nil, MTLPixelFormat, Int, Int, Int, inout CVMetalTextureRef)'
问题是,如果我将 outTexture 替换为 nil,它就会停止抛出错误,但显然这对我没有帮助。根据函数的参考,我需要 UnsafeMutablePointer?> 最后一个值。我不确定如何获得。
尽量提前分配你的textureCache,这里是我用的成员变量:
var _videoTextureCache : Unmanaged<CVMetalTextureCacheRef>?
然后我通过
在初始化方法中分配textureCacheCVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache)
其中 _context.device 是 MTLDevice。然后,在 captureOutput 方法中,我使用以下内容(注意,此处不包括错误检查)
var textureRef : Unmanaged<CVMetalTextureRef>?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache!.takeUnretainedValue(), imageBuffer, nil, MTLPixelFormat.BGRA8Unorm, width, height, 0, &textureRef)
希望对您有所帮助!
更新@peacer212 对Swift 3.
的回答您不再需要 Unmanaged
和 takeUnretainedValue
。所以代码应该是:
var textureCache: CVMetalTextureCache?
...
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _context.device, nil, &_videoTextureCache)
...
var textureRef : CVMetalTexture?
CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache!, imageBuffer, nil, .bgra8Unorm, width, height, 0, & textureRef)