Почему этот проект Xcode, использующий Metal для отображения выходных данных камеры, так сильно влияет на батарею, и как я могу сделать его лучше? - PullRequest
0 голосов
/ 17 сентября 2018

Я использую CoreImageHelpers в качестве основы использования металла для отображения отфильтрованного в реальном времени вывода через камеру. Проблема в том, что я неожиданно получаю сильный заряд батареи, когда ожидаю, что Metal будет работать намного лучше, чем обновление UIImageView или даже OpenGL.

Обновление: тест с моей раздвоенной версией , ИЛИ

Перед тестированием исходного проекта обязательно обновите пару вещей:

-В ImageView.swift функция draw () должна вызываться после commandBuffer.commit ()

-Открытие DispatchQueue.main.async вокруг connection.videoOrientation в captureOutput:

    DispatchQueue.main.async{
        connection.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!

    }

Я тестирую на iPhone 6s Plus, и один эффект CICMYKHalftone увеличивает уровень заряда батареи при просмотре в Debug Navigator.

Я думал, что использование этого представления Металла значительно повысит производительность, но, похоже, это не так, даже при работе с более низкой частотой кадров 25-30 кадров в секунду.

Есть ли что-то важное, что могло бы сделать использование батареи лучше, чем в других приложениях с эффектами живой камеры?

Обновления :

Еще одно обновление производительности, которое я добавил, - это настройка MTKView для предпочитаемого фрейм-макера, которую я установил на 30, поскольку по умолчанию он будет вызываться до 60 раз в секунду. Я комбинирую это с более низкой частотой кадров устройства, чтобы добиться лучшей производительности и меньшего воздействия батареи.

1 Ответ

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

Во-первых, поскольку вы управляете чертежом вручную (вызывая draw()), вы должны установить для свойства isPaused представления значение true.Если вы этого не сделаете, представление будет отображаться как при вызове этого, так и во внутреннем таймере.

Во-вторых, соотношение между renderImage() и draw() инвертируется.Наблюдатель image didSet не должен вызывать renderImage().Стоит позвонить draw().Вы должны иметь переопределение draw(_ rect: CGRect), которое выполняет работу renderImage() (минус вызов draw()).(Вы можете либо draw(_ rect: CGRect) позвонить renderImage(), либо просто переименовать renderImage() в draw(_ rect: CGRect).)

В зависимости от ваших точных потребностей вы также можете установить для enableSetNeedsDisplay значение true и изменитьimage didSet для вызова setNeedsDisplay() вместо draw().Это будет иметь немного большую задержку, но позволит избежать попыток рисовать слишком часто.

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