Swift - How to make CVImageBufferRef as CVPixelBufferRef

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

CMSampleBufferRef sampleBuffer = some value CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

How to do it fast?


 var pixelBuffer : CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer) 

gives an error: "Unmanaged <CVPixelBufferRef> does not convert to 'CVPixelBufferRef'


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

gives an error: 'CVImageBuffer' does not convert to 'CVPixelBufferRef'


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

gives an error: Cannot convert expression type 'CVPixelBufferRef' to enter 'CVPixelBufferRef'

+6
source share
3 answers

EDIT

This answer was given during the Swift beta. The solution now seems to be simpler as suggested by klinger

 var pixelBuffer : CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 

however, I will leave the previous answer for historical reasons :-)

PREVIOUS ANSWER

Look at the preliminary documents:

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

In particular, this statement

Duplicate types

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

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

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

Then this statement should work. It might take some tweaking before I ever worked with CMSampleBufferGetImageBuffer , and for that reason I'm not sure about the first line (buffer initialization)

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

Or soon

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

However, you asked for CVPixelBuffer. If the two types are fully compatible (I don’t know the basic API, so I assume casting between CVPixelBuffer and CVImageBuffer in objc is always safe), there is no “automatism” for this, you need to go through Unsafe Pointer.

Full code:

  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 (), which does not consume the save count, since CMSampleBufferGetImageBuffer () returns an unreachable object

+11
source

In Xcode 6 beta 6, this finally works:

var pixelBuffer : CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)

+5
source

The @LombaX solution did not work for me in the latest version, Xcode Beta5. Here is what worked:

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

Source: https://habr.com/ru/post/971296/


All Articles