Как я могу извлечь буфер изображения из captureOutput (didDrop samplebuffer)? - PullRequest
1 голос
/ 13 мая 2019

Мое приложение включает получение видеокадров с камеры и запуск на нем CoreML. Это будет отображаться в представлении. Для этого у меня есть AVCaptureSession (), который подключен к видеовыходу. Основная обработка CoreML выполняется в captureOutput (didOutput Samplebuffer). Каждая обработка кадра занимает около 0,15 секунды, что означает, что у меня будут некоторые пропущенные кадры. После завершения процесса CoreML у меня есть AVAssetWriter, который добавляет все эти кадры вместе и сохраняет его в телефонном справочнике.

Основная проблема, однако, в том, что в моем сценарии использования также требуется сохранение исходного видео, и это видео должно иметь ВЫСОКИЙ FPS, и, поскольку я могу получать кадры изображения только в captureOutput (didOutput), видео качество будет нестабильным.

Я пробовал следующее:

  1. Причина, по которой я использую AVAssetWriter, заключается в том, что здесь указано: https://forums.developer.apple.com/thread/98113#300885 то, что невозможно иметь AVCaptureVideoDataOutput и AVCaptureMovieFileOutput.

  2. Я также попытался извлечь буфер изображения из captureOutput (didDrop), используя guard let pixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) else {return}, но это дает мне ноль. Это потому, что 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()
}
...