Hi all,
Does anyone know how I can make a deep copy of CMSampleBuffer?
I currently have the following extension on CVPixelBuffer:
func copy() -> CVPixelBuffer {
precondition(CFGetTypeID(self) == CVPixelBufferGetTypeID(), "copy() cannot be called on a non-CVPixelBuffer")
var _copy : CVPixelBuffer?
CVPixelBufferCreate(
nil,
CVPixelBufferGetWidth(self),
CVPixelBufferGetHeight(self),
CVPixelBufferGetPixelFormatType(self),
CVBufferGetAttachments(self, CVAttachmentMode.shouldPropagate),
&_copy
)
guard let copy = _copy else { fatalError() }
CVPixelBufferLockBaseAddress(self, .readOnly)
CVPixelBufferLockBaseAddress(copy, CVPixelBufferLockFlags(rawValue: 0))
for plane in 0..<CVPixelBufferGetPlaneCount(self) {
let dest = CVPixelBufferGetBaseAddressOfPlane(copy, plane)
let source = CVPixelBufferGetBaseAddressOfPlane(self, plane)
let height = CVPixelBufferGetHeightOfPlane(self, plane)
let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(self, plane)
memcpy(dest, source, height * bytesPerRow)
}
CVPixelBufferUnlockBaseAddress(copy, CVPixelBufferLockFlags(rawValue: 0))
CVPixelBufferUnlockBaseAddress(self, .readOnly)
return copy
}
I use this in AVCaptureVideoDataOutputSampleBufferDelegate so that it doesn’t lock up:
extension SampleViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let copy = pixelBuffer.copy()
pixelBuffers.append(copy)
print("PixelBuffers: \(pixelBuffers.count)")
}
}
I can see that the pixelBuffers Array does contain all the CVPixelBuffers, but when I loop through the array and convert the CVPIxelBuffer to UIImage, the image is not displayed:
private func imageFromPixelBuffer(_ pixelBuffer: CVPixelBuffer) -> UIImage? {
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
let context = CIContext()
let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer))
if let cgImage = context.createCGImage(ciImage, from: imageRect) {
return UIImage(cgImage: cgImage, scale: UIScreen.main.scale, orientation: .right)
}
return nil
}
Could anyone assist with this problem?