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

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

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

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

Архитектура

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

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

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

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

Чтобы реализовать библиотеку OEM-поставщика, скопируйте файлы camera-extensions-stub в проект системной библиотеки. Эти файлы определяют интерфейс расширений камеры.

Файлы 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

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

  • 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 взаимодействуют с библиотекой поставщика для включения расширения. На следующей диаграмме показан сквозной поток на примере расширения Night:

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

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

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

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

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

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

  3. Создание экземпляров классов расширителей:

    Создает экземпляры классов Extender для расширения. Существует два типа расширителя: базовый расширитель и расширенный расширитель. Вы должны реализовать один тип расширения для всех расширений. Для получения дополнительной информации см. «Базовый расширитель» и «Расширенный расширитель» .

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

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

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    А для типа Advanced Extender:

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

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

  5. Инициализируйте повторитель, используя информацию о камере:

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

  6. Информация о запросе:

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

  7. Включите расширение на повторителе:

    Класс 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. Однако при проверке версии используются только основная и дополнительная версии.

Чтобы проверить версию, 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.

Внедрите Basic Extender для расширений, которые обрабатывают изображения в 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, вы должны правильно реализовать библиотеку поставщика для поддержки этих потоков, которые мы опишем более подробно в следующем разделе.

Расширения камеры2 Расширения 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 связываниеToLifecycle(lifecycleOwner, cameraSelector, предварительный просмотр,...)

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

Интерфейс Basic 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 в качестве заполнителей. Замените их именами реальных файлов, которые вы реализуете.

Базовый расширитель имеет следующие возможности:

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

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

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

БазовыйРасширительAppFlow1

Рисунок 3. Последовательность действий приложения 1 на Basic Extender

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

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

Последовательность действий 2: запрос информации

БазовыйРасширительAppFlow2

Рисунок 4. Последовательность действий приложения 2 на Basic Extender

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

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

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

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

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

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

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

БазовыйРасширительAppFlow3

Рисунок 5. Последовательность действий приложения 3 на Basic Extender

На приведенной выше диаграмме показан основной процесс включения предварительного просмотра и захвата с помощью расширения без какого-либо процессора. Это означает, что 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 .

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

См. последовательность действий на диаграмме ниже:

Процессор захвата

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

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

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

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

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

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

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

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

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

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

AdvancedAppFlow1

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

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

Последовательность действий 2: запрос информации

AdvancedAppFlow2

Рисунок 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: предварительный просмотр/съёмка фотографий с включенным расширением

AdvancedAppFlow3

Рисунок 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() выполняет очистку.

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

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

Для типа Basic 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-интерцензии Camerax Extensions расширения камеры для Camera2 и Camerax Extensions, которые реализуют 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 androidx.camera.extensions.impl <uses-library> которая определена в файле AndroidManifest.xml , которая определяется в файле camera-extensions , которая должна быть загружена. В 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 , так как это библиотека, которую ищет камера.
    • 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 сложна, например, поскольку для обработки изображений для обработки изображений для обработки изображений требуется пост -процессор, работающий на уровне приложения.

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

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

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