2

我目前正在尝试使用 VideoToolbox 对来自 的视频数据进行编码AVCaptureVideoDataOutput,但在selfVTCompressionOutputCallback.

我的代码如下:

...

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

...

效果很好,并且打印输出符合预期,但是一旦我尝试在self中添加对 的引用VTCompressionOutputCallback,它就会得到一个编译器错误说明

A C function pointer cannot be formed from a closure that captures context

如何self在回调中使用?

在此先感谢您的帮助。

4

1 回答 1

2

我想出了一个解决办法。

VTCompressionSessionCreate调用有一个参数,outputCallbackRefCon该参数将传递给VTCompressionOutputCallback.

通过将 self 包装成UnsafeMutableRawPointer这样

let unmanagedSelf = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())

我能够将该值传递到参数VTCompressionSessionCreaterefcon。在回调内部,我可以使用

let scopedSelf = Unmanaged<ViewController>.fromOpaque(unmanagedSelf).takeUnretainedValue()
于 2019-03-29T18:18:24.780 回答