从MTKView
中捕捉帧的最有效的方法是什么?如果可能的话,我想从实时帧中保存一个.mov文件。是否可以渲染成AVPlayer帧或其他东西?
当前正在使用以下代码绘制(基于@warrenm PerformanceShaders project):
func draw(in view: MTKView) {
_ = inflightSemaphore.wait(timeout: DispatchTime.distantFuture)
updateBuffers()
let commandBuffer = commandQueue.makeCommandBuffer()
commandBuffer.addCompletedHandler{ [weak self] commandBuffer in
if let strongSelf = self {
strongSelf.inflightSemaphore.signal()
}
}
// Dispatch the current kernel to perform the selected image filter
selectedKernel.encode(commandBuffer: commandBuffer,
sourceTexture: kernelSourceTexture!,
destinationTexture: kernelDestTexture!)
if let renderPassDescriptor = view.currentRenderPassDescriptor, let currentDrawable = view.currentDrawable
{
let clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 1)
renderPassDescriptor.colorAttachments[0].clearColor = clearColor
let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
renderEncoder.label = "Main pass"
renderEncoder.pushDebugGroup("Draw textured square")
renderEncoder.setFrontFacing(.counterClockwise)
renderEncoder.setCullMode(.back)
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setVertexBuffer(vertexBuffer, offset: MBEVertexDataSize * bufferIndex, at: 0)
renderEncoder.setVertexBuffer(uniformBuffer, offset: MBEUniformDataSize * bufferIndex , at: 1)
renderEncoder.setFragmentTexture(kernelDestTexture, at: 0)
renderEncoder.setFragmentSamplerState(sampler, at: 0)
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4)
renderEncoder.popDebugGroup()
renderEncoder.endEncoding()
commandBuffer.present(currentDrawable)
}
bufferIndex = (bufferIndex + 1) % MBEMaxInflightBuffers
commandBuffer.commit()
}
2条答案
按热度按时间1tu0hz3e1#
下面是一个小类,它执行编写电影文件的基本功能,该电影文件捕获Metal视图的内容:
初始化其中一个并调用
startRecording()
后,您可以向包含渲染命令的命令缓冲区添加一个预定处理程序并调用writeFrame
(在结束编码后,但在呈现可绘制对象或提交缓冲区之前):录制完成后,只需调用
endRecording
,视频文件将被最终确定并关闭。注意事项:
此类假设源纹理为默认格式
.bgra8Unorm
。如果不是,则会崩溃或损坏。如有必要,请使用计算或片段着色器转换纹理,或使用加速。这个类还假设纹理和视频帧大小相同。如果不是这样(如果可绘制的大小改变,或者你的屏幕自动旋转),输出将被破坏,你可能会看到崩溃。通过缩放或裁剪你的应用程序需要的源纹理来缓解这个问题。
6tqwzwtp2#
已升级到Swift 5
编辑:添加了
CVPixelBufferRelease(pixelBuffer)
以避免内存泄漏。如果没有这个,在每一帧新创建的pixelBuffer将留在内存中,最终应用程序将你所有的可用系统内存。