Swift - 如何将CVImageBufferRef转换为CVPixelBufferRef

8
在Objective-C中,您可以轻松地将CVImageBufferRef转换为CVPixelBufferRef:
CMSampleBufferRef sampleBuffer = some value

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

我该如何在Swift中实现这个功能?


var pixelBuffer : CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)

出现错误:'Unmanaged<CVPixelBufferRef>' 无法转换为 'CVPixelBufferRef'


var pixelBuffer : CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer).takeRetainedValue()

出现错误:'CVImageBuffer' 无法转换为 'CVPixelBufferRef'


var pixelBuffer : CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer).takeRetainedValue() as CVPixelBufferRef

出现错误:无法将表达式的类型“CVPixelBufferRef”转换为类型“CVPixelBufferRef”

3个回答

17

编辑

这个回答是在 Swift beta 测试期间给出的。现在根据 klinger 的建议,解决方案似乎更简单了。

var pixelBuffer : CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

然而出于历史原因,我将保留之前的回答 :-)

之前的回答

查看预发布文档:

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-XID_40

特别是这个声明:

重新映射类型

当Swift导入Core Foundation类型时,编译器会重新映射这些类型的名称。编译器从每个类型名称的末尾移除Ref,因为所有Swift类都是引用类型,因此后缀是冗余的。

Core Foundation CFTypeRef类型完全映射到AnyObject类型。在您编写的代码中,无论何时使用CFTypeRef,现在都应该使用AnyObject。

你想要做的第一件事是从每个类型中删除“ref”。但这不是必要的,因为“refs”已经被typealias为“non-ref”类型。

然后,这个声明应该可以工作。它可能需要一些微调,因为我之前从未使用过CMSampleBufferGetImageBuffer,因此对于第一行(初始化缓冲区)我不确定。

    var buf : CMSampleBuffer = // initialize the buffer
    var anUnmanaged : Unmanaged<CVImageBuffer> = CMSampleBufferGetImageBuffer(buf)
    var returnValue = anUnmanaged.takeUnretainedValue()

或者,简单来说

    var buf : CMSampleBuffer = // initialize the buffer
    var anUnmanaged : CVImageBuffer = CMSampleBufferGetImageBuffer(buf).takeRetainedValue()

然而,你要求一个CVPixelBuffer。如果这两种类型是完全兼容的(我不知道底层API,所以我假设在Objective-C中CVPixelBuffer和CVImageBuffer之间的转换总是安全的),那么就没有“自动化”来完成它,你必须通过一个Unsafe Pointer来传递。

完整代码如下:

    var buf : CMSampleBuffer = // initialize the buffer
    var anUnmanaged : Unmanaged<CVImageBuffer> = CMSampleBufferGetImageBuffer(buf)
    var returnValue = anUnmanaged.takeUnretainedValue()

    var anOpaque = anUnmanaged.toOpaque()
    var pixelBuffer : CVPixelBuffer = Unmanaged<CVPixelBuffer>.fromOpaque(anOpaque).takeUnretainedValue()

我使用了 takeUnretainedValue() 方法,该方法不会消耗引用计数,因为 CMSampleBufferGetImageBuffer() 返回的是未持有的对象。


1
谢谢!在Objective-C中,CVImageBufferRef是CVPixelBufferRef的同义词,这让我很疯狂。 - klinger
在这种情况下,我建议您提交一个错误-功能请求,以便在将来的版本中实现自动转换 :-) 我不排除有一些函数可以在两种类型之间进行桥接,但是通过不透明指针是我想到的第一个解决方案 :-) - LombaX

5
在Xcode 6 beta 6中,以下代码终于可用: var pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 该代码涉及IT技术。

1

@LombaX的解决方案在最新版本的Xcode Beta5中对我无效。以下是有效的方法:

let imageBuffer : CVImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let srcPtr = Unmanaged.passUnretained(imageBuffer).toOpaque()
let pixelBuffer = Unmanaged<CVPixelBuffer>.fromOpaque(srcPtr).takeUnretainedValue()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接