Today i have little problem and I can't understand what's happened. I'm trying to implement realtime applying CIFIlter(s) to image from video stream using MTKView without delegate. I have this error:
Take image and send to processing code:
extension CameraCamptureOperator: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
DispatchQueue.main.async {
connection.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue) ?? .portrait
}
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
DispatchQueue.main.async {[weak self] in
self?.delegate?.campturedNewImage(CIImage(cvImageBuffer: pixelBuffer))
}
}
}
In didSet image, I calling render():
private func renderingInProcess() {
guard let image = imageToDraw,
let targetTexture = mtkView.currentDrawable?.texture else { return }
let commandBuffer = GraphicApi.commandQueue?.makeCommandBuffer()
let render = mtkView.currentRenderPassDescriptor
render?.colorAttachments[0].clearColor = .init(red: 244.0/255.0, green: 241.0/255.0, blue: 238.0/255.0, alpha: 1.0)
let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: render!)
renderEncoder?.endEncoding()
let scaleX = mtkView.drawableSize.width / image.extent.width
let scaleY = mtkView.drawableSize.height / image.extent.height
let scale = min(scaleX, scaleY)
let scaledImage = image.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
var bounds = CGRect(origin: .zero, size: mtkView.drawableSize)
if scale == scaleX {
let space = (mtkView.drawableSize.height - scaledImage.extent.height) / 2
let origin = CGPoint(x: 0, y: -space)
bounds.origin = origin
} else {
let space = (mtkView.drawableSize.width - scaledImage.extent.width) / 2
let origin = CGPoint(x: -space, y: 0)
bounds.origin = origin
}
GraphicApi.context.render(scaledImage,
to: targetTexture,
commandBuffer: commandBuffer,
bounds: bounds,
colorSpace: GraphicApi.colorSpace)
commandBuffer!.present(mtkView.currentDrawable!)
commandBuffer!.commit()
}
[CAMetalLayerDrawable present] should not be called after already presenting this drawable. Get a nextDrawable instead.
[Common] _BSMachError: port 600b; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
Execution of the command buffer was aborted due to an error during execution. Discarded (victim of GPU error/recovery) (IOAF code 5)
2018-11-29 22:07:58.446854+0200 AVCIProject[1244:223735] [Common] _BSMachError: port 5597; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
code:
Code Block -(void)startRender() { dispatch_block_t renderBlock = ^ { @autoreleasepool { ...... ...... id<MTLTexture> drawingTexture = metalView.currentDrawable.texture; ...... passDescriptor.colorAttachments[0].texture = drawingTexture; ...... ...... [renderEncoder popDebugGroup]; [renderEncoder endEncoding]; [commandBuffer presentDrawable:[(CAMetalLayer*)metalView.layer nextDrawable] ]; [commandBuffer commit]; }}; ([NSThread isMainThread])?renderBlock():dispatch_async(dispatch_get_main_queue(), renderBlock); }
It may be in other background threads before rendering, when GPU start render, used dispatch_async(get_main), make sure render work in main thread.