У меня проблема в том, что иногда (1 из 250) videoImage
выдает ошибку SIGABRT
, возникающую из libc++abi.dylib: Pure virtual function called!
Я не совсем уверен, почему любой из них происходит. Я не испытал достаточно SIGABRT (кроме ошибок раскадровки), чтобы точно знать, как отлаживать.
private var videoImage: CIImage?
private var videoPixelBuffer: CVPixelBuffer?
func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {
// print(self.videoDevice.activeVideoMinFrameDuration, self.videoDevice.activeVideoMaxFrameDuration)
guard let syncedVideoData = synchronizedDataCollection.synchronizedData(for: self.videoDataOutput) as? AVCaptureSynchronizedSampleBufferData else { return }
guard !syncedVideoData.sampleBufferWasDropped else {
print(syncedVideoData.droppedReason.rawValue)
return
}
let videoSampleBuffer = syncedVideoData.sampleBuffer
let syncedDepthData = synchronizedDataCollection.synchronizedData(for: self.depthDataOutput) as? AVCaptureSynchronizedDepthData
var depthData = syncedDepthData?.depthData
if let syncedDepthData = syncedDepthData, syncedDepthData.depthDataWasDropped {
print("dropped depth:\(syncedDepthData)")
depthData = nil
}
let syncedMetaData = synchronizedDataCollection.synchronizedData(for: self.metadataOutput) as? AVCaptureSynchronizedMetadataObjectData
var face: AVMetadataObject? = nil
if let firstFace = syncedMetaData?.metadataObjects.first {
face = self.videoDataOutput.transformedMetadataObject(for: firstFace, connection: self.videoConnection)
}
guard let imagePixelBuffer = CMSampleBufferGetImageBuffer(videoSampleBuffer) else { fatalError() }
guard let depthMap = depthData?.depthDataMap else { return }
CVPixelBufferLockBaseAddress(imagePixelBuffer,
CVPixelBufferLockFlags.readOnly)
self.videoPixelBuffer = displayEqualizedPixelBuffer(pixelBuffer: imagePixelBuffer)
CVPixelBufferUnlockBaseAddress(imagePixelBuffer,
CVPixelBufferLockFlags.readOnly)
}
func displayEqualizedPixelBuffer(pixelBuffer: CVPixelBuffer, scaleToBuffer: CVPixelBuffer? = nil) -> CVPixelBuffer? {
let scaleWidth:Int = scaleToBuffer != nil ? CVPixelBufferGetWidth(scaleToBuffer!) : CVPixelBufferGetWidth(pixelBuffer)
let scaleHeight:Int = scaleToBuffer != nil ? CVPixelBufferGetHeight(scaleToBuffer!) : CVPixelBufferGetHeight(pixelBuffer)
let flags = CVPixelBufferLockFlags(rawValue: 0)
guard kCVReturnSuccess == CVPixelBufferLockBaseAddress(pixelBuffer, flags) else {
return nil
}
defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, flags) }
guard let srcData = CVPixelBufferGetBaseAddress(pixelBuffer) else {
print("Error: could not get pixel buffer base address")
return nil
}
let srcBytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
var srcBuffer = vImage_Buffer(data: srcData,
height: vImagePixelCount(CVPixelBufferGetHeight(pixelBuffer)),
width: vImagePixelCount(CVPixelBufferGetWidth(pixelBuffer)),
rowBytes: srcBytesPerRow)
let destBytesPerRow = scaleWidth*4
guard let destData = malloc(scaleHeight*destBytesPerRow) else {
print("Error: out of memory")
return nil
}
var destBuffer = vImage_Buffer(data: destData,
height: vImagePixelCount(scaleHeight),
width: vImagePixelCount(scaleWidth),
rowBytes: destBytesPerRow)
let error = vImageScale_ARGB8888(&srcBuffer, &destBuffer, nil, vImage_Flags(kvImageLeaveAlphaUnchanged))
if error != kvImageNoError {
print("Error:", error)
free(destData)
return nil
}
let releaseCallback: CVPixelBufferReleaseBytesCallback = { _, ptr in
if let ptr = ptr {
free(UnsafeMutableRawPointer(mutating: ptr))
}
}
let pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer)
var dstPixelBuffer: CVPixelBuffer?
let status = CVPixelBufferCreateWithBytes(nil, scaleWidth, scaleHeight,
pixelFormat, destData,
destBytesPerRow, releaseCallback,
nil, nil, &dstPixelBuffer)
if status != kCVReturnSuccess {
print("Error: could not create new pixel buffer")
free(destData)
return nil
}
return dstPixelBuffer
}
videoImage = CIImage(cvPixelBuffer: videoPixelBuffer)
print(videoImage)
Это обратный след:
thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00000001953b6efc libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x00000001952d68b8 libsystem_pthread.dylib`pthread_kill + 228
frame #2: 0x0000000195266a74 libsystem_c.dylib`abort + 104
frame #3: 0x000000019537e3c8 libc++abi.dylib`abort_message + 132
frame #4: 0x000000019538c740 libc++abi.dylib`__cxa_pure_virtual + 24
frame #5: 0x0000000196e95fe0 CoreImage`-[CIImage extent] + 32
frame #6: 0x0000000196e961c4 CoreImage`-[CIImage description] + 44
frame #7: 0x00000001cb06439c libswiftFoundation.dylib`merged protocol witness for Swift.CustomStringConvertible.description.getter : Swift.String in conformance __C.NSObject : Swift.CustomStringConvertible in Foundation + 24
frame #8: 0x00000001a2eb6ee0 libswiftCore.dylib`function signature specialization <Arg[1] = Exploded, Arg[2] = Exploded> of generic specialization <Swift._Stdout> of Swift._print<A where A: Swift.TextOutputStream>(_: Swift.Array<Any>, separator: Swift.String, terminator: Swift.String, to: inout A) -> () + 1172
frame #9: 0x00000001a2d81c6c libswiftCore.dylib`Swift.print(_: Any..., separator: Swift.String, terminator: Swift.String) -> () + 32
* frame #10: 0x00000001037ca360 DepthCamera`specialized RealtimeDepthMaskViewController.draw(self=0x000000011d805c00) at RealTimeDepthViewController.swift:524:13 [opt]
frame #11: 0x00000001037c5000 DepthCamera`@objc RealtimeDepthMaskViewController.draw(in:) [inlined] DepthCamera.RealtimeDepthMaskViewController.draw(in: __C.MTKView) -> () at <compiler-generated>:0 [opt]
frame #12: 0x00000001037c4ffc DepthCamera`@objc RealtimeDepthMaskViewController.draw(in:) at <compiler-generated>:499 [opt]