Расширения камеры

Производители устройств могут предоставлять сторонним разработчикам такие расширения, как боке, ночной режим и HDR, через интерфейс Camera Extensions, предоставляемый библиотекой OEM-поставщика. Разработчики могут использовать API Camera2 Extensions и API CameraX Extensions для доступа к расширениям, реализованным в библиотеке OEM-поставщика.

Список поддерживаемых расширений, который одинаков для Camera2 и CameraX, см. в CameraX Extensions API . Если вы хотите добавить расширение, отправьте сообщение об ошибке в Issue Tracker .

На этой странице описывается, как реализовать и включить библиотеку OEM-поставщика на устройствах.

Архитектура

Следующая диаграмма описывает архитектуру интерфейса расширений камеры или extensions-interface : Архитектура

Рисунок 1. Архитектурная схема расширений камеры

Как показано на схеме, для поддержки расширений камеры вам необходимо реализовать extensions-interface предоставляемый библиотекой поставщика OEM. Ваша библиотека поставщика OEM включает два API: API расширений CameraX и API расширений Camera2 , которые используются приложениями CameraX и Camera2 соответственно для доступа к расширениям поставщиков.

Внедрить библиотеку OEM-поставщиков

Для внедрения библиотеки OEM-поставщика скопируйте файлы camera-extensions-stub в проект системной библиотеки. Эти файлы определяют интерфейс Camera Extensions.

Файлы camera-extensions-stub делятся на следующие категории:

Необходимые файлы интерфейса (не изменять)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

Обязательные реализации (добавьте свою реализацию)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Классы расширения Bokeh (реализуйте их, если расширение Bokeh поддерживается)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

Классы расширения Night (реализуйте их, если поддерживается расширение Night)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

Классы автоматического расширения (реализуйте их, если поддерживается автоматическое расширение)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

Классы расширения HDR (реализуйте их, если поддерживается расширение HDR)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

Классы расширения Face Retouch (реализуйте его, если расширение Face Retouch поддерживается)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

Утилиты (необязательно, можно удалить)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

Вам не обязательно предоставлять реализацию для каждого расширения. Если вы не реализуете расширение, установите isExtensionAvailable() для возврата false или удалите соответствующие классы Extender. API расширений Camera2 и CameraX сообщают приложению, что расширение недоступно.

Давайте рассмотрим, как API Camera2 и CameraX Extensions взаимодействуют с библиотекой поставщика для включения расширения. Следующая диаграмма иллюстрирует сквозной поток на примере расширения Night:

Основной поток

Рисунок 2. Реализация ночного расширения

  1. Проверка версии:

    Camera2/X вызывает ExtensionVersionImpl.checkApiVersion() , чтобы убедиться, что версия extensions-interface реализованная OEM, совместима с поддерживаемыми версиями Camera2/X.

  2. Инициализация библиотеки поставщика:

    InitializerImpl имеет метод init() , который инициализирует библиотеку поставщика. Camera2/X завершает инициализацию перед доступом к классам Extender.

  3. Классы Instantiate Extender:

    Создает экземпляры классов Extender для расширения. Существует два типа Extender: Basic Extender и Advanced Extender. Необходимо реализовать один тип Extender для всех Extensions. Для получения дополнительной информации см. Basic Extender против Advanced Extender .

    Camera2/X создает экземпляры классов Extender и взаимодействует с ними для извлечения информации и включения расширения. Для заданного расширения Camera2/X может создавать экземпляры классов Extender несколько раз. В результате не выполняйте тяжелую инициализацию в конструкторе или вызове init() . Выполняйте тяжелую работу только перед началом сеанса камеры, например, когда вызывается onInit() в Basic Extender или initSession() в Advanced Extender.

    Для расширения Night создаются следующие классы Extender для типа Basic Extender:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    А для типа Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Проверить доступность расширения:

    Перед включением расширения isExtensionAvailable() проверяет, доступно ли расширение для указанного идентификатора камеры через экземпляр Extender.

  5. Инициализируйте расширитель с информацией о камере:

    Camera2/X вызывает init() для экземпляра Extender и передает ему идентификатор камеры и CameraCharacteristics .

  6. Запрос информации:

    Вызывает класс Extender для получения информации, такой как поддерживаемые разрешения, по-прежнему фиксирует предполагаемую задержку и захватывает ключи запроса от Extender в рамках подготовки к включению расширения.

  7. Включить расширение на Extender:

    Класс Extender предоставляет все интерфейсы, необходимые для включения класса. Он предлагает механизм для подключения OEM-реализации к конвейеру Camera2, например, для внедрения параметров запроса захвата или включения постпроцессора.

    Для типа Advanced Extender Camera2/X взаимодействует с SessionProcessorImpl для включения расширения. Camera2/X извлекает экземпляр SessionProcessorImpl , вызывая createSessionProcessor() в Extender.

В следующих разделах процесс расширения описывается более подробно.

Проверка версии

При загрузке библиотеки OEM-поставщика с устройства во время выполнения Camera2/X проверяет, совместима ли библиотека с версией extensions-interface . extensions-interface использует семантическое управление версиями, или MAJOR.MINOR.PATCH, например, 1.1.0 или 1.2.0. Однако во время проверки версий используются только major и minor версии.

Для проверки версии Camera2/X вызывает ExtensionVersionImpl.checkApiVersion() с поддерживаемой версией extensions-interface . Затем Camera2/X использует версию, сообщенную библиотекой OEM, чтобы определить, можно ли включить расширение и какие возможности оно должно вызывать.

Совместимость с основными версиями

Если основные версии интерфейса расширения Camera2/X и библиотеки поставщика различаются, то расширение считается несовместимым и отключается.

Обратная совместимость

Пока основная версия идентична, Camera2/X обеспечивает обратную совместимость с библиотеками OEM-поставщиков, созданными с предыдущими версиями extensions-interface . Например, если Camera2/X поддерживает extensions-interface 1.3.0, библиотеки OEM-поставщиков, которые реализовали 1.0.0, 1.1.0 и 1.2.0, по-прежнему совместимы. Это также означает, что после реализации определенной версии библиотеки поставщика Camera2/X обеспечивает обратную совместимость библиотеки с будущими версиями extension-interface .

Совместимость с предыдущими версиями

Прямая совместимость с библиотеками поставщиков новых extensions-interface зависит от вас, OEM. Если вам нужны некоторые функции для реализации расширений, вы можете включить расширения, начиная с определенной версии. В этом случае вы можете вернуть поддерживаемую версию extensions-interface , когда версия библиотеки Camera2/X соответствует требованиям. Если версии Camera2/X не поддерживаются, вы можете вернуть несовместимую версию, например 99.0.0, чтобы отключить расширения.

Инициализация библиотеки поставщика

После проверки версии extensions-interface реализованной библиотекой OEM, Camera2/X начинает процесс инициализации. Метод InitializerImpl.init() сигнализирует библиотеке OEM, что приложение пытается использовать расширения.

Camera2/X не выполняет никаких других вызовов в библиотеку OEM (кроме проверки версии) до тех пор, пока библиотека поставщика OEM не вызовет OnExtensionsInitializedCallback.onSuccess() для уведомления о завершении инициализации.

Необходимо реализовать InitializerImpl с extensions-interface 1.1.0. Camera2/X пропускает этап инициализации библиотеки, если библиотека поставщика OEM реализует extensions-interface 1.0.0.

Базовый удлинитель против расширенного удлинителя

Существует два типа реализации extensions-interface : Basic Extender и Advanced Extender. Advanced Extender поддерживается с версии extensions-interface 1.2.0.

Реализуйте базовый расширитель для расширений, которые обрабатывают изображения в HAL камеры или используют постпроцессор, способный обрабатывать потоки YUV.

Реализуйте Advanced Extender для расширений, которым необходимо настраивать конфигурацию потока Camera2 и отправлять запросы на захват по мере необходимости.

Для сравнения смотрите следующую таблицу:

Базовый удлинитель Расширенный удлинитель
Конфигурации потока Зафиксированный
Предварительный просмотр: PRIVATE или YUV_420_888 (если процессор существует)
Фотоснимок: JPEG или YUV_420_888 (если есть процессор)
Возможность настройки OEM-производителем.
Отправка запроса на захват Только Camera2/X может отправлять запросы на захват. Вы можете задать параметры для этих запросов. Когда процессор предоставляется для захвата изображения, Camera2/X может отправлять несколько запросов на захват и отправлять все изображения и результаты захвата процессору. Экземпляр RequestProcessorImpl предоставляется вам для выполнения запроса захвата камеры2 и получения результатов и изображения.

Camera2/X вызывает startRepeating и startCapture в SessionProcessorImpl , чтобы подать OEM-производителю сигнал о необходимости начать повторяющийся запрос на предварительный просмотр и начать последовательность захвата неподвижных изображений соответственно.

Крючки в трубопроводе камеры
  • onPresetSession предоставляет параметры сеанса.
  • onEnableSession отправляет один запрос сразу после настройки CameraCaptureSession .
  • onDisableSession отправляет один запрос перед закрытием CameraCaptureSession .
  • initSession инициализирует и возвращает настроенную конфигурацию сеанса camera2 для создания сеанса захвата.
  • onCaptureSessionStart вызывается сразу после настройки CameraCaptureSession .
  • onCaptureSessionEnd вызывается перед закрытием CameraCaptureSession .
Подходит для Расширения, реализованные в HAL камеры или в процессоре, обрабатывающем изображения YUV.
  • Имеет реализации расширений на основе Camera2.
  • Требуется индивидуальная конфигурация потока, например поток RAW.
  • Требуется интерактивная последовательность захвата.
Поддерживаемая версия API Расширения Camera2: Android 13 или выше
Расширения CameraX: camera-extensions 1.1.0 или выше
Расширения Camera2: Android 12L или выше
Расширения CameraX: camera-extensions 1.2.0-alpha03 или выше

Потоки приложений

В следующей таблице показаны три типа потоков приложений и соответствующие им вызовы API расширений камеры. Хотя Camera2/X предоставляет эти API, необходимо правильно реализовать библиотеку поставщика для поддержки этих потоков, которые мы более подробно опишем в следующем разделе.

Расширения Camera2 Расширения CameraX
Запросить доступность расширения CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Запрос информации CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX обрабатывает остальную информацию в библиотеке.

Предварительный просмотр и стоп-кадр с включенным расширением CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...)

Базовый удлинитель

Интерфейс Basic Extender обеспечивает хуки в нескольких местах в конвейере камеры. Каждый тип расширения имеет соответствующие классы Extender, которые OEM-производителям необходимо реализовать.

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

Реализуемые классы-расширители
Ночь NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Авто AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
Боке BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
Ретушь лица BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

В следующем примере мы используем PreviewExtenderImpl и ImageCaptureExtenderImpl в качестве заполнителей. Замените их именами реальных файлов, которые вы реализуете.

Basic Extender имеет следующие возможности:

  • Внедрите параметры сеанса при настройке CameraCaptureSession ( onPresetSession ).
  • Уведомляет вас о событиях начала и закрытия сеанса захвата и отправляет один запрос на уведомление HAL с возвращаемыми параметрами ( onEnableSession , onDisableSession ).
  • Внедрите параметры захвата для запроса ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Добавьте процессоры для предварительного просмотра и захвата неподвижных изображений, способные обрабатывать поток YUV_420_888 .

Давайте посмотрим, как Camera2/X вызывает extensions-interface для реализации трех потоков приложений, упомянутых выше.

Поток приложения 1: проверка доступности расширения

BasicExtenderAppFlow1

Рисунок 3. Поток приложения 1 на базовом расширителе

В этом потоке Camera2/X напрямую вызывает метод isExtensionAvailable() как PreviewExtenderImpl , так и ImageCaptureExtenderImpl без вызова init() . Оба класса Extender должны возвращать true для включения расширений.

Это часто первый шаг для приложений, чтобы проверить, поддерживается ли данный тип расширения для данного идентификатора камеры, прежде чем включать расширение. Это связано с тем, что некоторые расширения поддерживаются только для определенных идентификаторов камеры.

Поток приложения 2: Запрос информации

BasicExtenderAppFlow2

Рисунок 4. Поток приложения 2 на базовом расширителе

Определив, доступно ли расширение, приложения должны запросить следующую информацию, прежде чем включать расширение.

  • Диапазон задержки захвата неподвижного изображения: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange возвращает диапазон задержки захвата, чтобы приложение могло оценить, целесообразно ли включать расширение для текущего сценария.

  • Поддерживаемые размеры для поверхности предварительного просмотра и захвата: ImageCaptureExtenderImpl.getSupportedResolutions и PreviewExtenderImpl.getSupportedResolutions возвращают список форматов изображений и размеров, поддерживаемых для формата и размера поверхности.

  • Поддерживаемые ключи запроса и результата: Camera2/X вызывает следующие методы для извлечения поддерживаемых ключей запроса захвата и ключей результата из вашей реализации:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X всегда сначала вызывает init() для этих классов Extender, прежде чем запрашивать дополнительную информацию.

Поток приложения 3: Предварительный просмотр/захват неподвижного изображения с включенным расширением (реализация HAL)

BasicExtenderAppFlow3

Рисунок 5. Поток приложения 3 на базовом расширителе

На приведенной выше схеме показан основной поток включения предварительного просмотра и захвата неподвижных изображений с расширением без процессора. Это означает, что HAL камеры обрабатывает расширение.

В этом потоке Camera2/X сначала вызывает init() , а затем onInit , который уведомляет вас о том, что сеанс камеры вот-вот начнется с указанными расширениями. Вы можете выполнить тяжелую инициализацию в onInit() .

При настройке CameraCaptureSession Camera2/X вызывает onPresetSession для получения параметров сеанса. После успешной настройки сеанса захвата Camera2/X вызывает onEnableSession , возвращая экземпляр CaptureStageImpl , содержащий параметры захвата. Camera2/X немедленно отправляет один запрос с этими параметрами захвата, чтобы уведомить HAL. Аналогично, перед закрытием сеанса захвата Camera2/X вызывает onDisableSession , а затем отправляет один запрос с возвращенными параметрами захвата.

Повторяющийся запрос, вызванный Camera2/X, содержит параметры запроса, возвращаемые PreviewExtenderImpl.getCaptureStage() . Кроме того, запрос на захват неподвижного изображения содержит параметры, возвращаемые ImageCaptureExtenderImpl.getCaptureStages() .

Наконец, Camera2/X вызывает onDeInit() после завершения сеанса камеры. Вы можете освободить ресурсы в onDeinit() .

Процессор предварительного просмотра

Помимо HAL камеры, можно также реализовать расширения в процессоре.

Реализуйте PreviewExtenderImpl.getProcessorType , чтобы указать тип процессора, как описано ниже:

  • PROCESSOR_TYPE_NONE : Нет процессора. Изображения обрабатываются в HAL камеры.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : тип процессора позволяет обновлять повторяющийся запрос новыми параметрами запроса захвата на основе последнего TotalCaptureResult .

    PreviewExtenderImpl.getProcessor должен возвращать экземпляр RequestUpdateProcessorImpl , который обрабатывает экземпляр TotalCaptureResult и возвращает экземпляр CaptureStageImpl для обновления повторяющегося запроса. PreviewExtenderImpl.getCaptureStage() также должен отражать результат обработки и возвращать последний CaptureStageImpl .

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : этот тип позволяет реализовать процессор для обработки изображений YUV_420_888 и записи вывода на PRIVATE поверхность.

    Вам необходимо реализовать и вернуть экземпляр PreviewImageProcessorImpl в PreviewExtenderImpl.getProcessor . Процессор отвечает за обработку входных изображений YUV_420_888 . Он должен записывать выходные данные в формат PRIVATE предварительного просмотра. Camera2/X использует поверхность YUV_420_888 вместо PRIVATE для настройки CameraCaptureSession для предварительного просмотра.

    Смотрите следующую иллюстрацию для потока:

Предварительный просмотрПроцессор

Рисунок 6. Поток предварительного просмотра с помощью PreviewImageProcessorImpl

Интерфейс PreviewImageProcessorImpl расширяет ProcessImpl и имеет три важных метода:

  • onOutputSurface(Surface surface, int imageFormat) устанавливает выходную поверхность для процессора. Для PreviewImageProcessorImpl imageFormat — это формат пикселей, например PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) устанавливает размер входного изображения.

  • onImageFormatUpdate(int imageFormat) устанавливает формат входного изображения. В настоящее время это может быть только YUV_420_888 .

Процессор захвата изображений

Для захвата неподвижных изображений можно реализовать процессор, вернув экземпляр CaptureProcessorImpl с помощью ImageCaptureExtenderImpl.getCaptureProcessor . Процессор отвечает за обработку списка захваченных изображений YUV_420_888 и экземпляров TotalCaptureResult и запись вывода на поверхность YUV_420_888 .

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

Смотрите поток на схеме ниже:

CaptureProcessor

Рисунок 7. Поток захвата с помощью CaptureProcessorImpl

  1. Camera2/X использует формат поверхности YUV_420_888 для захвата неподвижных изображений, чтобы настроить сеанс захвата. Camera2/X подготавливает CaptureProcessorImpl , вызывая:

    • CaptureProcessorImpl.onImageFormatUpdate() с YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() с размером входного изображения.
    • CaptureProcessorImpl.onOutputSurface() с выходной поверхностью YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages возвращает список CaptureStageImpl , где каждый элемент сопоставляется с экземпляром CaptureRequest с параметрами захвата, которые отправляются Camera2/X. Например, если он возвращает список из трех экземпляров CaptureStageImpl , Camera2/X отправляет три запроса захвата с соответствующими параметрами захвата, используя API captureBurst .

  3. Полученные изображения и экземпляры TotalCaptureResult объединяются и отправляются в CaptureProcessorImpl для обработки.

  4. CaptureProcessorImpl записывает результирующее изображение (формат YUV_420_888 ) на выходную поверхность, указанную вызовом onOutputSurface() . Camera2/X при необходимости преобразует его в изображения JPEG.

Поддержка ключей и результатов запроса захвата

В дополнение к предварительному просмотру и захвату камеры, приложения могут устанавливать масштабирование, параметры вспышки или активировать функцию фокусировки по нажатию. Эти параметры могут быть несовместимы с реализацией вашего расширения.

В extensions-interface 1.3.0 были добавлены следующие методы, позволяющие вам раскрывать параметры, поддерживаемые вашей реализацией:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() возвращает ключи запроса захвата, поддерживаемые вашей реализацией.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() возвращает ключи результата захвата, содержащиеся в результате захвата.

Если HAL камеры обрабатывает расширение, Camera2/X извлекает результаты захвата в CameraCaptureSession.CaptureCallback . Однако, если процессор реализован, Camera2/X извлекает результаты захвата в ProcessResultImpl , который передается методу process() в PreviewImageProcessorImpl и CaptureProcessorImpl . Вы несете ответственность за сообщение результата захвата через ProcessResultImpl в Camera2/X.

См. определение интерфейса CaptureProcessorImpl ниже в качестве примера. В extensions-interface 1.3.0 или выше вызывается второй вызов process() :

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

Для обычных операций с камерой, таких как масштабирование, фокусировка по касанию, вспышка и компенсация экспозиции, мы рекомендуем поддерживать следующие клавиши как для запроса на захват, так и для результата захвата:

  • Увеличить:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Фокусировка нажатием:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Вспышка:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Компенсация экспозиции:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Для базовых расширителей, реализующих 1.2.0 или более ранние версии, API расширений CameraX явно поддерживает все указанные выше ключи. Для extensions-interface 1.3.0 и CameraX, и Camera2 учитывают возвращенный список и поддерживают только содержащиеся в нем ключи. Например, если вы решили возвращать только CaptureRequest#CONTROL_ZOOM_RATIO и CaptureRequest#SCALER_CROP_REGION в реализации 1.3.0, то это означает, что для приложения поддерживается только зум, а фокусировка касанием, вспышка и компенсация экспозиции не допускаются.

Расширенный удлинитель

Advanced Extender — это тип реализации поставщика на основе API Camera2. Этот тип Extender был добавлен в extensions-interface 1.2.0. В зависимости от производителя устройства расширения могут быть реализованы на уровне приложения, что зависит от следующих факторов:

  • Пользовательская конфигурация потока: настройте пользовательские потоки, такие как поток RAW, или используйте несколько потоков для разных идентификаторов физических камер.

  • Возможность отправки запросов Camera2: поддержка сложной логики взаимодействия, которая может отправлять запросы захвата с параметрами, основанными на результатах предыдущих запросов.

Advanced Extender предоставляет оболочку или промежуточный уровень, позволяющий настраивать конфигурацию потока и отправлять запросы на захват по требованию.

Файлы для реализации

Для переключения на реализацию Advanced Extender метод isAdvancedExtenderImplemented() в ExtensionVersionImpl должен возвращать true . Для каждого типа расширения OEM-производители должны реализовать соответствующие классы Extender. Файлы реализации Advanced Extender находятся в расширенном пакете.

Реализуемые классы-расширители
Ночь advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Авто advanced/AutoAdvancedExtenderImpl.java
Боке advanced/BokehAdvancedExtenderImpl.java
Ретушь лица advanced/BeautyAdvancedExtenderImpl.java

В следующем примере мы используем AdvancedExtenderImpl в качестве заполнителя. Замените его на имя файла Extender для расширения, которое вы реализуете.

Давайте посмотрим, как Camera2/X вызывает extensions-interface для реализации трех потоков приложения.

Поток приложения 1: проверка доступности расширений

РасширенныйAppFlow1

Рисунок 8. Поток приложения 1 на Advanced Extender

Сначала приложение проверяет, поддерживается ли данное расширение.

Поток приложения 2: Запрос информации

РасширенныйAppFlow2

Рисунок 9. Поток приложения 2 на Advanced Extender

После вызова AdvancedExtenderImpl.init() приложение может запросить следующую информацию о AdvancedExtenderImpl :

  • Расчетная задержка захвата неподвижного изображения: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() возвращает диапазон задержки захвата, чтобы приложение могло оценить, целесообразно ли включать расширение для текущего сценария.

  • Поддерживаемые разрешения для предварительного просмотра и фотосъемки:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() возвращает карту формата изображения в список размеров, которые поддерживаются для формата и размера поверхности предварительного просмотра. OEM-производители должны поддерживать как минимум формат PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() возвращает поддерживаемый формат и размеры для поверхности захвата неподвижных объектов. OEM-производители должны поддерживать вывод форматов JPEG и YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() возвращает поддерживаемые размеры для дополнительного потока YUV_420_888 для анализа изображений. Если поверхность анализа изображений YUV не поддерживается, getSupportedYuvAnalysisResolutions() должен возвращать null или пустой список.

  • Доступные ключи/результаты запроса захвата (добавлены в extensions-interface 1.3.0): Camera2/X вызывает следующие методы для извлечения поддерживаемых ключей запроса захвата и ключей результатов из вашей реализации:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Для получения дополнительной информации см. раздел Ключи и результаты запроса на захват поддержки .

Поток приложения 3: предварительный просмотр/захват неподвижного изображения с включенным расширением

РасширенныйAppFlow3

Рисунок 10. Поток приложения 3 на Advanced Extender

На диаграмме выше показан основной поток для запуска предварительного просмотра и захвата неподвижного изображения для типа Advanced Extender. Давайте рассмотрим каждый шаг.

  1. Экземпляр SessionProcessorImpl

    Основная реализация Advanced Extender находится в SessionProcessorImpl , который отвечает за предоставление настраиваемой конфигурации сеанса и отправку запросов захвата для инициирования предварительного просмотра и запроса на неподвижный захват. AdvancedExtenderImpl.createSessionProcessor() вызывается для возврата экземпляра SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() инициализирует сессию для расширения. Здесь вы выделяете ресурсы и возвращаете конфигурацию сессии для подготовки CameraCaptureSession .

    Для входных параметров Camera2/X определяет конфигурации выходной поверхности для предварительного просмотра, захвата неподвижных изображений и дополнительного анализа изображения YUV. Эта конфигурация выходной поверхности ( OutputSurfaceImpl ) содержит поверхность, размер и формат изображения, которые извлекаются следующими методами в AdvancedExtenderImpl :

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    Вы должны вернуть экземпляр Camera2SessionConfigImpl , который состоит из списка экземпляров Camera2OutputConfigImpl и параметров сеанса, используемых для настройки CameraCaptureSession . Вы несете ответственность за вывод корректных изображений с камеры на выходные поверхности, переданные Camera2/X. Вот несколько параметров для включения вывода:

    • Обработка в HAL камеры: Вы можете напрямую добавлять выходные поверхности в CameraCaptureSession с реализацией SurfaceOutputConfigImpl . Это настраивает предоставленную выходную поверхность для конвейера камеры и позволяет HAL камеры обрабатывать изображение.
    • Обработка промежуточной поверхности ImageReader (RAW, YUV и т. д.): добавьте промежуточные поверхности ImageReader в CameraCaptureSession с экземпляром ImageReaderOutputConfigImpl .

      Вам необходимо обработать промежуточные изображения и записать результирующее изображение на выходную поверхность.

    • Использовать совместное использование поверхности Camera2: использовать совместное использование поверхности с другой поверхностью, добавив любой экземпляр Camera2OutputConfigImpl в метод getSurfaceSharingOutputConfigs() другого экземпляра Camera2OutputConfigImpl . Формат и размер поверхности должны быть идентичны.

    Все Camera2OutputConfigImpl , включая SurfaceOutputConfigImpl и ImageReaderOutputConfigImpl должны иметь уникальный идентификатор ( getId() ), который используется для указания целевой поверхности и извлечения изображения из ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart и RequestProcessorImpl

    Когда запускается CameraCaptureSession и фреймворк Camera вызывает onConfigured() , то Camera2/X вызывает SessionProcessorImpl.onCaptureSessionStart() с оболочкой запроса Camera2 RequestProcessImpl . Camera2/X реализует RequestProcessImpl , что позволяет выполнять запросы захвата и извлекать изображения , если используется ImageReaderOutputConfigImpl .

    API RequestProcessImpl аналогичны API Camera2 CameraCaptureSession с точки зрения выполнения запросов. Различия следующие:

    • Целевая поверхность указывается идентификатором экземпляра Camera2OutputConfigImpl .
    • Возможность извлечения изображения из ImageReader .

    Вы можете вызвать RequestProcessorImpl.setImageProcessor() с указанным идентификатором Camera2OutputConfigImpl , чтобы зарегистрировать экземпляр ImageProcessorImpl для получения изображений.

    Экземпляр RequestProcessImpl становится недействительным после того, как Camera2/X вызывает SessionProcessorImpl.onCaptureSessionEnd() .

  4. Запустите предварительный просмотр и сделайте снимок

    В реализации Advanced Extender вы можете отправлять запросы захвата через интерфейс RequestProcessorImpl . Camera2/X уведомляет вас о необходимости начать повторяющийся запрос на предварительный просмотр или последовательность неподвижного захвата, вызывая SessionProcessorImpl#startRepeating и SessionProcessorImpl#startCapture соответственно. Вам следует отправлять запросы захвата для удовлетворения этих запросов на предварительный просмотр и неподвижный захват.

    Camera2/X также устанавливает параметры запроса захвата через SessionProcessorImpl#setParameters . Вы должны установить эти параметры запроса (если параметры поддерживаются) как для повторяющихся, так и для одиночных запросов.

    Необходимо поддерживать как минимум CaptureRequest.JPEG_ORIENTATION и CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 поддерживает ключи запроса и результата, которые предоставляются следующими методами:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    Когда разработчики задают ключи в списке getAvailableCaptureRequestKeys , необходимо включить параметры и убедиться, что результат захвата содержит ключи в списке getAvailableCaptureResultKeys .

  5. startTrigger

    SessionProcessorImpl.startTrigger() вызывается для запуска триггера, такого как CaptureRequest.CONTROL_AF_TRIGGER и CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Вы можете игнорировать любые ключи запроса захвата, которые не были объявлены в AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() поддерживается с extensions-interface 1.3.0. Он позволяет приложениям реализовывать фокусировку по нажатию и вспышку с расширениями.

  6. Очистить

    При завершении сеанса захвата SessionProcessorImpl.onCaptureSessionEnd() вызывается перед закрытием CameraCaptureSession . После закрытия сеанса захвата deInitSession() выполняет очистку.

Поддержка предварительного просмотра, захвата стоп-кадров и анализа изображений

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

Для основного типа Extender, независимо от того, чтобы включить расширение для предварительного просмотра, вы должны реализовать как ImageCaptureExtenderImpl , так и PreviewExtenderImpl для данного расширения. Часто в приложении также используется поток YUV для анализа содержимого изображения, например, поиск QR -кодов или текста. Чтобы лучше поддерживать этот вариант использования, вы должны поддерживать комбинацию потока предварительного просмотра, все еще захвата и потока YUV_420_888 для настройки CameraCaptureSession . Это означает, что если вы реализуете процессор, вам нужно поддерживать комбинацию потока трех потоков YUV_420_888 .

Для Advanced Extender Camera2/X передает три выходных поверхностей на вызов SessionProcessorImpl.initSession() . Эти выходные поверхности предназначены для предварительного просмотра, все еще захвата и анализа изображений соответственно. Вы должны убедиться, что предварительный просмотр и до сих пор захватывают выходные поверхности, показывают действительный вывод. Однако для выходной поверхности анализа изображения убедитесь, что она работает только тогда, когда она не ноль. Если ваша реализация не может поддержать поток анализа изображений, вы можете вернуть пустой список в AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . Это гарантирует, что выходная поверхность анализа изображений всегда нулевой в SessionProcessorImpl.initSession() .

Поддержка захвата видео

Текущая архитектура расширения камеры поддерживает только предварительный просмотр и до сих пор захватывает варианты использования. Мы не поддерживаем включение расширения на поверхностях MediaCodec или MediaRecorder для записи видео. Тем не менее, приложения могут записать вывод предварительного просмотра.

Поддержка поверхностей MediaCodec и MediaRecorder находится под следствием.

Специфичные для расширения метаданные

Для Android 14 и выше, специфичные для расширения метаданные позволяют клиентам по расширению камеры устанавливать и получать настройки и результаты запроса на расширение и получать. В частности, клиенты расширения камеры могут использовать параметр запроса захвата EXTENSION_STRENGTH для управления прочностью расширения и результат захвата EXTENSION_CURRENT_TYPE , чтобы указать включенный тип расширения.

Запросы на захват

Параметр запроса захвата EXTENSION_STRENGTH контролирует силу эффекта постобработки расширения. Соответствующий результат захвата включает значение прочности по умолчанию, если этот параметр не установлен явно клиентом. Этот параметр может быть применен следующим образом для этих типов расширения:

  • BOKEH : контролирует количество размытия.
  • HDR и NIGHT : управляет количеством слитых изображений и яркостью конечного изображения.
  • FACE_RETOUCH : контролирует количество косметического улучшения и сглаживания кожи.

Поддерживаемый диапазон для параметра EXTENSION_STRENGTH составляет от 0 до 100 , а 0 указывает на обработку удлинения или простую пропуск и 100 указывающие максимальную прочность на удлинение эффекта обработки.

Чтобы добавить поддержку для EXTENSION_STRENGTH , используйте API -интерфейсы специфических параметров поставщика, представленные в версии 1.3.0 интерфейса библиотеки расширения. Для получения дополнительной информации см. getAvailableCaptureRequestKeys() .

Захват результаты

Результат захвата EXTENSION_CURRENT_TYPE Let Enginations уведомляет клиентов о типе активного расширения.

Поскольку расширения, использующие AUTO тип динамического переключения между типами расширения, такими как HDR и NIGHT в зависимости от условий сцены, приложения расширения камеры могут использовать EXTENSION_CURRENT_TYPE для отображения информации о текущем расширении, выбранном AUTO Extension.

В реальном времени по-прежнему оценить оценку задержки

Для Android 14 и выше клиенты по расширению камеры могут запросить в режиме реального времени оценки задержки на основе сцены и условий окружающей среды с использованием getRealtimeStillCaptureLatency() . Этот метод обеспечивает более точные оценки, чем статический метод getEstimatedCaptureLatencyRangeMillis() метод. Основываясь на оценке задержки, приложения могут решить пропустить обработку расширения или отобразить указание, чтобы уведомлять пользователей о долгосрочной операции.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

Для поддержки в режиме реального времени все еще захватывают оценки задержки, реализуйте следующее:

Захват обработки обработки прогресса

Для Android 14 и выше клиенты по расширению камеры могут получать обратные вызовы для прогресса в долгосрочной перемещении, которые все еще захватывают операции обработки. Приложения могут отображать текущий прогресс для пользователей для улучшения общего пользовательского опыта.

Приложения могут использовать следующий код для интеграции этой функции:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{

  class AppCallbackImpl extends ExtensionCaptureCallback {

    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }

}

Чтобы поддержать обратные вызовы обработки обработки захвата, реализация вашего поставщика расширения должна вызвать следующие обратные вызовы с текущим значением прогресса:

Пост -просмотр по -прежнему захват

Для Android 14 и выше, расширения камеры могут предоставить пост -обзор (предварительное изображение), используя setPostviewOutputConfiguration . Чтобы улучшить пользовательский опыт, приложения могут отображать изображение после просмотра в качестве заполнителя, когда расширение испытывает повышенную задержку обработки, и заменить изображение, когда доступно конечное изображение. Приложения могут настроить и выдавать запросы по захвату пост -просмотра с помощью следующего эталонного кода:

{

if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}

ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);

CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();

}

Для поддержки пост -просмотра по -прежнему захват, реализация вашего поставщика должна реализовать следующее:

Поддержка SurfaceView выход

Для Android 14 и выше клиенты по расширению камеры могут использовать пути для оптимизированного предварительного просмотра мощности и производительности, зарегистрировав экземпляр SurfaceView для предварительного просмотра вывода для повторных запросов.

Для поддержки выхода SurfaceView ваш реализация расширения поставщика должна быть способна потоковой передаче и выводу предварительного просмотра в экземпляры SurfaceView . Чтобы убедиться, что это поддерживается, запустите модуль SurfaceViewExtensionPreviewTest.java CTS.

Типы сеансов конкретных поставщиков

Функция позволяет реализациям расширения поставщиков выбирать тип сеанса конкретного поставщика, который будет установлен во внутреннем сеансе захвата камеры вместо значения по умолчанию.

Функция полностью работает в рамках и стеке поставщиков и не имеет видимого воздействия API клиента/общественности.

Чтобы выбрать тип сеанса, специфичный для поставщика, реализуйте следующее для ваших библиотек расширения: * ExtenderStateListener.onSessionType() для основных расширений * Camera2SessionConfigImpl.getSessionType() для расширенных расширений

История версии интерфейса расширений

В следующей таблице показана история версии интерфейса расширения камеры. Вы всегда должны реализовать библиотеку поставщиков с последней версией.

Версия Добавлены функции
1.0.0
  • Проверка версии
    • ExtensionVersionImpl
  • Основной расширитель
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Инициализация библиотеки
    • InitializerImpl
  • Разоблачить поддерживаемые решения
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Получить расчетную задержку захвата
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Разоблачить поддерживаемые клавиши/клавиши запроса на захват захвата
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys и getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys и getAvailableCaptureResultKeys
    • New process() вызов, который принимает ProcessResultImpl в PreviewImageProcessorImpl и CaptureProcessorImpl
    • Запрос типа триггера поддержки
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Специфичные для расширения метаданные
  • Динамическая по -прежнему захватывает оценки задержки
  • Захват обработки обработки прогресса
  • Пост -просмотр по -прежнему захват
  • Поддержка вывода SurfaceView
  • Типы сеансов конкретных поставщиков

Референтная реализация

Следующие справочные реализации библиотеки OEM -поставщиков доступны в frameworks/ex .

  • advancedSample : базовая реализация Advanced Extender.

  • sample : базовая реализация основного удлинителя.

  • service_based_sample : реализация, которая демонстрирует, как размещать расширения камеры в Service . Эта реализация содержит следующие компоненты:

    • oem_library : API API API- Extensions-Interface . Это действует как проход, который пересылает вызовы от Extensions-Interface в сервис. Эта библиотека также предоставляет файлы AIDL и классы обертки для связи с службой.

      Advanced Extender включен по умолчанию. Чтобы включить базовый удлинитель, измените ExtensionsVersionImpl#isAdvancedExtenderImplemented чтобы вернуть false .

    • extensions_service : образец реализации службы расширений. Добавьте свою реализацию здесь. Интерфейс для реализации в службе аналогичен Extensions-Interface . Например, реализация IAdvancedExtenderImpl.Stub выполняет те же операции, что и AdvancedExtenderImpl . ImageWrapper и TotalCaptureResultWrapper должны сделать Image и TotalCaptureResult .

Установите библиотеку поставщиков на устройстве

Библиотека поставщиков OEM не встроена в приложение; Он загружен с устройства во время выполнения Camera2/X. В Camerax библиотека <uses-library> , которая определена в файле androidx.camera.extensions.impl , которая определяется в файле AndroidManifest.xml , которая должна быть загружена. В Camera2 фреймворк загружает службу camera-extensions , которая также заявляет, что <uses-library> библиотека <использует> библиотеку androidx.camera.extensions.impl во время выполнения.

Это позволяет сторонним приложениям, используя расширения для автоматической загрузки библиотеки поставщиков OEM. Библиотека OEM отмечена необязательной, поэтому приложения могут работать на устройствах, у которых нет библиотеки на устройстве. Camera2/X обрабатывает это поведение автоматически, когда приложение пытается использовать расширение камеры, если производитель устройств помещает библиотеку OEM на устройство, чтобы его можно было обнаружить приложением.

Чтобы настроить библиотеку OEM на устройстве, сделайте следующее:

  1. Добавьте файл разрешений, который требуется тегом <uses-library> , используя следующий формат: /etc/permissions/ ANY_FILENAME .xml . Например, /etc/permissions/camera_extensions.xml . Файлы в этом каталоге предоставляют сопоставление библиотеки, названной в <uses-library> на фактический путь файла на устройстве.
  2. Используйте пример ниже, чтобы добавить необходимую информацию в файл.

    • name должно быть androidx.camera.extensions.impl , так как это библиотека, которую ищет камера.
    • file - это абсолютный путь файла, который содержит реализацию расширений (например, /system/framework/androidx.camera.extensions.impl.jar ).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>

В Android 12 или выше устройства, поддерживающие расширения камеры, должны иметь свойство ro.camerax.extensions.enabled , установленное в true , что позволяет запрашивать, поддерживает ли устройство расширения. Для этого добавьте следующую строку в файл, создайте файл:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Проверка

Чтобы проверить вашу реализацию библиотеки OEM-поставщиков на этапе разработки, используйте пример приложения на androidx-main/camera/integration-tests/extensionstestapp/ , которое проходит через различные расширения поставщиков.

После того, как вы завершите свою реализацию, используйте инструмент проверки расширений камеры для запуска автоматизированных и ручных тестов, чтобы убедиться, что библиотека поставщиков реализована правильно.

Расширенный режим сцены по сравнению с расширениями камеры

Для расширения Bokeh, в дополнение к тому, что он вызывает его с помощью расширений камеры, вы можете выявить расширение, используя расширенный режим сцены, который включен через клавишу CONTROL_EXTENDED_SCENE_MODE . Для получения дополнительной информации о реализации см. Camera Bokeh .

Режим расширенной сцены имеет меньше ограничений по сравнению с расширениями камеры для приложений Camera2. Например, вы можете включить расширенный режим сцены в обычном экземпляре CameraCaptureSession , который поддерживает гибкие комбинации потока и параметры запроса захвата. Напротив, расширения камеры поддерживают только фиксированный набор типов потоков и имеют ограниченную поддержку для параметров запроса захвата.

Недостатком расширенного режима сцены является то, что вы можете реализовать его только в камере HAL, что означает, что он должен быть проверен для работы на всех ортогональных элементах управления, доступных для разработчиков приложений.

Мы рекомендуем разоблачить Боке, используя как расширенный режим сцены, так и расширения камеры, потому что приложения могут предпочесть использовать конкретный API для включения BOKEH. Мы рекомендуем сначала использовать расширенный режим сцены, потому что это наиболее гибкий способ для приложений, чтобы включить расширение Bokeh. Затем вы можете реализовать интерфейс расширения камеры на основе расширенного режима сцены. Если внедрить Bokeh в камере HAL сложна, например, поскольку для обработки изображений для обработки изображений для обработки изображений требуется пост -процессор, работающий на уровне приложения.

Часто задаваемые вопросы (FAQ)

Есть ли какие -либо ограничения на уровни API?

Да Это зависит от набора функций API Android, который требуется реализацией библиотеки OEM -поставщиков. Например, ExtenderStateListener.onPresetSession() использует вызов SessionConfiguration.setSessionParameters() для набора базового набора тегов. Этот вызов доступен только на уровне API 28 и выше. Для получения подробной информации о конкретных методах интерфейса см. Справочную документацию API .