Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - How do you cast a CVImageBufferRef as a CVPixelBufferRef

Tags:

swift

In objective-c you can easily cast a CVImageBufferRef as a CVPixelBufferRef:

CMSampleBufferRef sampleBuffer = some value

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

How can I do this in swift?


var pixelBuffer : CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)

gives the error: 'Unmanaged<CVPixelBufferRef>' is not convertible to 'CVPixelBufferRef'


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

gives the error: 'CVImageBuffer' is not convertible to 'CVPixelBufferRef'


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

gives the error: Cannot convert the expression's type 'CVPixelBufferRef' to type 'CVPixelBufferRef'

like image 617
klinger Avatar asked Jun 24 '14 15:06

klinger


1 Answers

EDIT

This answer was given during Swift beta test period. It seems that now the solution is simpler, as suggested by klinger

var pixelBuffer : CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

however I'll leave the previous answer for historycal reasons :-)

PREVIOUS ANSWER

Look at the prerelease docs:

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

Specifically this statement

Remapped Types

When Swift imports Core Foundation types, the compiler remaps the names of these types. The compiler removes Ref from the end of each type name because all Swift classes are reference types, therefore the suffix is redundant.

The Core Foundation CFTypeRef type completely remaps to the AnyObject type. Wherever you would use CFTypeRef, you should now use AnyObject in your code.

The first thing you would like to do, is to remove the "ref" from each type. However it's not necessary, since the "refs" are typealiased to the "non-ref" types.

Then, this statement should work. It may need some tuning before I've never worked with CMSampleBufferGetImageBuffer, and for this reason I'm not sure about the first line (initialize the buffer)

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

Or, shortly

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

However, you asked for a CVPixelBuffer. If the two types are fully compatible (I don't know the underlying API so I assume that casting between CVPixelBuffer and CVImageBuffer in objc is always safe), there is no "automatism" to do it, you have to pass through an Unsafe Pointer.

The complete code is this:

    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()

I used takeUnretainedValue() that doesn't consume a retain count, since CMSampleBufferGetImageBuffer() returns an unretained object

like image 147
LombaX Avatar answered Oct 21 '22 18:10

LombaX