Камеры переключения AVFoundation медленные (подключены к буферу выборки) - PullRequest
0 голосов
/ 19 сентября 2018
override func viewDidLoad() {
    super.viewDidLoad()
    ...
    setupDevice()
    setupInputOutput()
}

Просмотр загружен запускает цепочку установки

 func setupDevice() {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices {
        if device.position == AVCaptureDevice.Position.back {
            backCamera = device
            setupCorrectFramerate(currentCamera: backCamera!)
        }
        else if device.position == AVCaptureDevice.Position.front {
            frontCamera = device
            setupCorrectFramerate(currentCamera: frontCamera!)
        }
    }
    currentCamera = cameraModeIsBack ? backCamera : frontCamera
}

var deviceInput: AVCaptureDeviceInput?
let videoOutput = AVCaptureVideoDataOutput()

func setupInputOutput() {
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
        deviceInput = captureDeviceInput
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1280x720

        if captureSession.canAddInput(deviceInput!) {
            captureSession.addInput(deviceInput!)
        }
        videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "sample buffer delegate", attributes: []))
        if captureSession.canAddOutput(videoOutput) {
            captureSession.addOutput(videoOutput)
        }
        captureSession.startRunning()
        if(firstTime){
            setupMetal()
        }
        firstTime = false
        toggleCamerButton.isEnabled = true
    } catch {
        print(error)
    }
}

На высоком уровне я нахожу входы устройства, настраиваю их частоту кадров и настраиваю сеанс захвата (выходные данные буфера обрабатываются в MTKView).

Проблема в том, когда я меняю камеры.Он либо мгновенный, либо не работает, либо становится очень медленным и зависает на 4-5 секунд, прежде чем ответить.

Логика, которую я использую для смены камер:

func updateCameras(){
    DispatchQueue.global().async {
        self.captureSession.stopRunning()
        self.captureSession.removeInput(self.deviceInput!)
        self.currentCamera = self.cameraModeIsBack ? self.backCamera : self.frontCamera
        self.changeCameras()
    }
}


func changeCameras(){
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
        self.deviceInput = captureDeviceInput
        if self.captureSession.canAddInput(self.deviceInput!) {
            self.captureSession.addInput(self.deviceInput!)
        }
        self.captureSession.startRunning()
       DispatchQueue.main.async {
            self.toggleCamerButton.isEnabled = true
       }
    } catch {
        print(error)
    }

}

Я пересмотрел ее столько жекак я могу.Переключение камер по существу

  1. Остановка сеанса камеры
  2. удаление входа
  3. добавление входа
  4. начало сеанса

Понятия не имею, с какой стати он так изменчив (в большинстве случаев отлично работает на моем iPhone X, а на iPhone 6 - всегда медленно).

1 Ответ

0 голосов
/ 19 сентября 2018

Я подозреваю, что вызовы для манипулирования cameraSession должны выполняться в главном потоке.Попробуйте изменить updateCameras(), чтобы использовать DispatchQueue.main.async() вместо DispatchQueue.global().async

Вот так:

func updateCameras(){
    DispatchQueue.main.async {
        self.captureSession.stopRunning()
        self.captureSession.removeInput(self.deviceInput!)
        self.currentCamera = self.cameraModeIsBack ? self.backCamera : self.frontCamera
        self.changeCameras()
    }
}

С этим изменением вызов на DispatchQueue.main.async() в вашей функции changeCameras() не долженбольше нужно будет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...