如何从captureOutput(didDrop samplebuffer)中提取图像缓冲区?

时间:2019-05-13 17:07:43

标签: ios swift avfoundation avassetwriter

我的应用程序涉及从摄像机获取视频帧并在其上运行CoreML。然后,它将显示在视图上。为此,我有一个连接到视频输出的AVCaptureSession()。 CoreML的主要处理是在captureOutput(didOutput Samplebuffer)中完成的。帧的每次处理大约需要0.15秒,这意味着我将丢掉一些帧。完成CoreML处理后,我有一个AVAssetWriter将所有这些帧附加在一起,并将其保存在电话目录中。

但是,主要问题是,我的用例还需要保存原始视频,并且该视频应具有HIGH FPS,并且由于我只能在captureOutput(didOutput)中获取图像帧,因此该视频质量会不稳定。

我尝试了以下方法:

  1. 我使用AVAssetWriter的原因是因为这里给出了这样的提示:https://forums.developer.apple.com/thread/98113#300885不能同时拥有AVCaptureVideoDataOutput和AVCaptureMovieFileOutput。

  2. 我也尝试过使用guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)else {return}从captureOutput(didDrop)中提取图像缓冲区,但它给了我零。这是因为sampleBuffer仅包含元数据,但不包含图像缓冲区,如下所述:https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutputsamplebufferdelegate/1388468-captureoutput

这是我的一些代码:

    func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { /* HOW DO I possibly extract an image buffer here from the dropped frames here? */ }


    func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    let inputVideoImage = UIImage(pixelBuffer: pixelBuffer)

    if self.isRecording{
        let sourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        if let camera = self.videoWriterVideoInput, camera.isReadyForMoreMediaData {
            videoWriterQueue.async() { 
                self.videoWriterInputPixelBufferAdaptor.append(pixelBuffer, withPresentationTime: sourceTime)
            }
        }else{
            print("AVAssetInput is not ready for more media data ... ")
        }
    }

   runCoreML()
}

0 个答案:

没有答案