Intereting Posts
Предотвратите ошибку Android «process is bad» Как оставаться в позиции прокрутки в RecyclerView после добавления элементов в свой первый индекс и вызывать notifydatasetchange Связывание статических библиотек в android ndk Интерактивный фильтр для медиаплеера (видеоигра Youtube) После отправки данных на сервер, как печатать ответ в следующем действии? Уведомления стека в Kitkat (API 19) с использованием setGroup () не работают Нужна помощь по внедрению 47degree Android-SwipeListView Как показать логотип, иконку, заголовок, субтитры панели инструментов, когда они завернуты в CollapsingToolbarLayout? Как скрыть нижнюю системную панель в Android-планшете MediaCodec с поверхностным входом: запись в фоновом режиме Жизненный цикл активности Android – для чего все эти методы? ClassCastException в PreferenceActivity Android Dropdown-Menu (нет счетчика!) Как преобразовать строку Base64 в образ BitMap, чтобы показать его в ImageView? Объявления Youtube перед целевым видео

Предварительный обратный вызов в Camera2 значительно медленнее, чем в Camera1

Это 2017 год, и я, наконец, начинаю переход с Camera1 на Camera2. В Camera1 я очень полагался на setPreviewCallbackWithBuffer() для выполнения обработки в реальном времени, однако в Camera2 это работает намного медленнее до такой степени, что становится почти непригодным.

Для сравнения, на Moto G3 Camera1 можно легко производить 30-40 FPS, а на Camera2 я не мог получить более 10-15 FPS.

Вот как я создаю ImageReader

 imageReader = ImageReader .newInstance( previewSize.width, // size is around 1280x720 previewSize.height, ImageFormat.YUV_420_888, // note, it is not JPEG 2 // max number of images, does not really affect performance ); imageReader.setOnImageAvailableListener( callback, CameraThread.getInstance().createHandler() ); 

Сам обратный вызов выполняет минимально возможную работу:

 Image image = reader.acquireNextImage(); image.close(); 

Я уже проверял подобные ответы, например, этот . Однако их проблема заключается в том, что они используют формат изображения JPEG вместо YUV_420_888 .

Как добиться производительности, аналогичной Camera1?

Solutions Collecting From Web of "Предварительный обратный вызов в Camera2 значительно медленнее, чем в Camera1"

Это просто наблюдение, но я все равно отправлю его.

Вы говорите, что регистрируете OnImageAvailableListener . Этот слушатель не доставляет изображения, а ссылку на тот же ImageReader вы подписаны. И тогда вы должны позвонить либо acquireLatestImage либо acquireNextImage чтобы получить фактическое изображение.

В документах есть абзац, который может быть полезен для понимания того, что происходит:

Данные изображения инкапсулируются в объекты Image , и к ним можно одновременно обращаться к нескольким таким объектам, вплоть до номера, указанного параметром конструктора maxImages . Новые изображения, отправленные в ImageReader через его поверхность, помещаются в очередь до тех пор, пока не будут доступны через acquireLatestImage() или acquireNextImage() . Из-за ограничений памяти источник изображения в конечном итоге сместит или сбросит изображения, пытаясь отобразить на поверхности, если ImageReader не получает и не отпускает изображения со скоростью, равной скорости производства.

Поэтому некоторые вещи, которые могут помочь:

  • Запросить большую память в манифесте
  • Передайте достаточно maxImages аргумент maxImages конструктору ImageReader (вы получите IllegalStateException если вы все равно исчерпаете очередь).
  • Предпочитаете acquireLatestImage над acquireNextImage для обработки в реальном времени. Этот метод автоматически acquireNextImage старые изображения, а другой – нет, и, таким образом, использование acquireNextImage по ошибке будет все более acquireNextImage доставку изображений до тех пор, пока у вас не закончится память.