问题
I'm currently trying to use VideoToolbox to encode video data from an AVCaptureVideoDataOutput
, but I'm having an issue referencing self
from within the VTCompressionOutputCallback
.
My code is as follows:
...
var sessionRef: VTCompressionSession?
let outputCallback: VTCompressionOutputCallback = { _, _, status, _, sampleBuffer in
guard status == noErr, let sampleBuffer = sampleBuffer else {
return
}
debugPrint("[INFO]: outputCallback: sampleBuffer: \(sampleBuffer)")
}
let sessionErr = VTCompressionSessionCreate(allocator: nil,
width: width,
height: height,
codecType: kCMVideoCodecType_H264,
encoderSpecification: nil,
imageBufferAttributes: nil,
compressedDataAllocator: nil,
outputCallback: outputCallback,
refcon: nil,
compressionSessionOut: UnsafeMutablePointer(&sessionRef))
...
That works fine, and the print outputs as expected, but as soon as I try and add a reference to self
within the VTCompressionOutputCallback
, it get a compiler error stating
A C function pointer cannot be formed from a closure that captures context
How can I use self
from within the callback?
Thanks in advance for the help.
回答1:
I figured out a solution.
The VTCompressionSessionCreate
call has a parameter for outputCallbackRefCon
which gets passed along to the VTCompressionOutputCallback
.
By wrapping self in an UnsafeMutableRawPointer
like so
let unmanagedSelf = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
I was able to pass that value into the VTCompressionSessionCreate
under the refcon
parameter. Inside of the callback I was then able to do pull that value back out using
let scopedSelf = Unmanaged<ViewController>.fromOpaque(unmanagedSelf).takeUnretainedValue()
来源:https://stackoverflow.com/questions/55421039/referencing-self-from-within-a-vtcompressionoutputcallback