Расширения для камер

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

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

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

Архитектура

На следующей схеме показана архитектура интерфейса Camera Extensions или extensions-interface: Архитектура

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

Как показано на диаграмме, для поддержки Camera Extensions необходимо реализовать extensions-interface, предоставляемый библиотекой поставщика OEM. Ваша библиотека поставщика OEM позволяет использовать два API: CameraX Extensions API и Camera2 Extensions API. Они используются приложениями 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 extender (реализуйте, если расширение Night поддерживается)

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

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

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

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

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

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

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

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

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

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

Давайте посмотрим, как API расширений Camera2 и CameraX взаимодействуют с библиотекой поставщика, чтобы включить расширение. На приведенной ниже диаграмме показан весь процесс с использованием расширения Night в качестве примера.

Mainflow

Рисунок 2. Как реализовать ночное расширение

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

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

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

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

  3. Создание экземпляров классов Extender

    Создает экземпляры классов Extender для расширения. Существует два типа расширителей: базовый и расширенный. Для всех расширений необходимо реализовать один тип Extender. Подробнее о базовом и расширенном удлинителе…

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

    Для расширения "Ночь" создаются следующие классы расширений для базового типа расширения:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Для расширенного типа:

    • 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 используется семантическое управление версиями в формате "МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ", например 1.1.0 или 1.2.0. Однако при проверке версии используются только основные и промежуточные версии.

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

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

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

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

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

Прямая совместимость

Обратная совместимость с библиотеками поставщиков более новых версий extensions-interface зависит от вас, производителя оборудования. Если для работы расширений требуются определенные функции, вы можете включить расширения, начиная с определенной версии. В этом случае вы можете вернуть поддерживаемую версию 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 пропускает шаг инициализации библиотеки, если библиотека поставщика оборудования реализует extensions-interface 1.0.0.

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

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

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

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

Сравнение приведено в таблице ниже.

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

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

Хуки в конвейере камеры
  • onPresetSession – параметры сеанса.
  • onEnableSession отправляет один запрос сразу после настройки CameraCaptureSession.
  • onDisableSession отправляет один запрос до закрытия CameraCaptureSession.
  • initSession инициализирует и возвращает настроенную конфигурацию сеанса camera2 для создания сеанса захвата.
  • Метод onCaptureSessionStart вызывается сразу после настройки CameraCaptureSession.
  • onCaptureSessionEnd вызывается до закрытия CameraCaptureSession.
Подходит для Расширения, реализованные в HAL камеры или в процессоре, который обрабатывает изображения YUV.
  • Реализации расширений на основе Camera2.
  • Требуется настроить поток, например использовать необработанный поток.
  • Требуется интерактивная последовательность захвата.
Поддерживаемая версия 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-производители.

В таблице ниже перечислены классы Extender, которые 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.

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

    Ниже показана схема процесса.

PreviewProcessor

Рисунок 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 записывает результат Image (формат 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. Вы должны передавать результат съемки в Camera2/X через ProcessResultImpl.

Ниже приведено определение интерфейса 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
  • Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Экспокоррекция:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

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

Расширитель Advanced

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

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

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

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

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

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

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

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

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

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

AdvancedAppFlow1

Рисунок 8. Процесс в приложении 1 на расширенном повторителе

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

Схема 2. Запрос информации

AdvancedAppFlow2

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

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

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

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

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

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() возвращает поддерживаемые форматы и размеры для поверхности захвата неподвижного изображения. Производители оригинального оборудования должны поддерживать вывод в форматах JPEG и YUV_420_888.

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

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

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Подробнее о ключах запросов и результатах захвата…

Сценарий 3. Предпросмотр или съемка с включенным расширением

AdvancedAppFlow3

Рисунок 10. Приложение 3 на устройстве 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. Это позволяет настроить предоставленную выходную поверхность для конвейера камеры и разрешить аппаратно-зависимому уровню камеры обработать изображение.
    • Обработка промежуточной поверхности ImageReader (RAW, YUV и т. д.). Добавьте промежуточные поверхности ImageReader в CameraCaptureSession с экземпляром ImageReaderOutputConfigImpl.

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

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

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

  3. onCaptureSessionStart и RequestProcessorImpl

    Когда запускается CameraCaptureSession и фреймворк камеры вызывает 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. Как запустить предварительный просмотр и сделать снимок

    В расширенной реализации 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. Удаление ненужных объектов

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

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

Расширение следует применять как для предварительного просмотра, так и для съемки. Однако если задержка слишком велика, чтобы плавно показывать предпросмотр, вы можете применить расширение только для фотосъемки.

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

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

Поддержка записи видео

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

Мы рассматриваем возможность поддержки платформ MediaCodec и MediaRecorder.

Метаданные, относящиеся к расширениям

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

Запросы на получение данных

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

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

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

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

Результаты сканирования

Результат захвата EXTENSION_CURRENT_TYPE позволяет реализациям расширений уведомлять клиентов об активном типе расширения.

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

Оценка задержки при съемке в реальном времени

В 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.javaCTS.

Типы сеансов, относящиеся к поставщику

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

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

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

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

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

Версия Добавленные функции
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
    • Новый вызов process(), который занимает ProcessResultImpl в PreviewImageProcessorImpl и CaptureProcessorImpl
    • Запрос на поддержку типа триггера
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Метаданные, относящиеся к расширениям
  • Динамические оценки задержки при съемке фотографий
  • Обратные вызовы для отслеживания прогресса обработки захвата
  • Конверсии после просмотра
  • Поддержка выходных данных SurfaceView
  • Типы сеансов, относящиеся к определенному поставщику

Пример реализации

В frameworks/ex доступны следующие реализации справочных библиотек поставщиков оборудования:

  • advancedSample – базовая реализация расширенного расширителя.

  • sample: базовый вариант расширителя.

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

    • oem_library: Библиотека OEM-расширений камеры для Camera2 и CameraX Extensions API, реализующая Extensions-Interface. Он действует как шлюз, который перенаправляет вызовы из Extensions-Interface в сервис. Эта библиотека также содержит файлы AIDL и классы-оболочки для взаимодействия с сервисом.

      Расширенный экстендер включен по умолчанию. Чтобы включить базовый расширитель, измените 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 библиотеки camera-extensions, является зависимостью CameraX и должна быть загружена во время выполнения. В Camera2 фреймворк загружает сервис расширений, который также объявляет, что <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, так как это библиотека, которую ищет CameraX.
    • 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 и более поздних версиях на устройствах, поддерживающих расширения CameraX, свойство ro.camerax.extensions.enabled должно иметь значение true. Это позволяет запрашивать информацию о том, поддерживает ли устройство расширения. Для этого добавьте в файл производителя устройства следующую строку:

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

Проверка

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

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

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

Чтобы использовать расширение боке, его можно добавить не только с помощью расширений камеры, но и с помощью расширенного режима съемки, который включается с помощью ключа CONTROL_EXTENDED_SCENE_MODE. Подробнее о боке камеры…

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

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

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

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

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

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