Производители устройств могут предоставлять сторонним разработчикам такие расширения, как боке, ночной режим и HDR, через интерфейс Camera Extensions, предоставляемый библиотекой OEM-поставщика. Разработчики могут использовать API Camera2 Extensions и API CameraX Extensions для доступа к расширениям, реализованным в библиотеке OEM-поставщика.
Список поддерживаемых расширений, который одинаков для Camera2 и CameraX, см. в CameraX Extensions API . Если вы хотите добавить расширение, отправьте сообщение об ошибке в Issue Tracker .
На этой странице описывается, как реализовать и включить библиотеку OEM-поставщика на устройствах.
Архитектура
Следующая диаграмма описывает архитектуру интерфейса расширений камеры или extensions-interface
:
Рисунок 1. Архитектурная схема расширений камеры
Как показано на схеме, для поддержки расширений камеры вам необходимо реализовать extensions-interface
предоставляемый библиотекой поставщика OEM. Ваша библиотека поставщика OEM включает два API: API расширений CameraX и API расширений Camera2 , которые используются приложениями CameraX и Camera2 соответственно для доступа к расширениям поставщиков.
Внедрить библиотеку OEM-поставщиков
Для внедрения библиотеки OEM-поставщика скопируйте файлы camera-extensions-stub
в проект системной библиотеки. Эти файлы определяют интерфейс Camera Extensions.
Файлы camera-extensions-stub
делятся на следующие категории:
Необходимые файлы интерфейса (не изменять)
-
PreviewExtenderImpl.java
-
ImageCaptureExtenderImpl.java
-
ExtenderStateListener.java
-
ProcessorImpl.java
-
PreviewImageProcessorImpl.java
-
CaptureProcessorImpl.java
-
CaptureStageImpl.java
-
RequestUpdateProcessorImpl.java
-
ProcessResultImpl.java
-
advanced/AdvancedExtenderImpl.java
-
advanced/Camera2OutputConfigImpl.java
-
advanced/Camera2SessionConfigImpl.java
-
advanced/ImageProcessorImpl.java
-
advanced/ImageReaderOutputConfigImpl.java
-
advanced/ImageReferenceImpl.java
-
advanced/MultiResolutionImageReaderOutputConfigImpl.java
-
advanced/OutputSurfaceImpl.java
-
advanced/RequestProcessorImpl.java
-
advanced/SessionProcessorImpl.java
-
advanced/SurfaceOutputConfigImpl.java
Обязательные реализации (добавьте свою реализацию)
-
ExtensionVersionImpl.java
-
InitializerImpl.java
Классы расширения Bokeh (реализуйте их, если расширение Bokeh поддерживается)
-
BokehImageCaptureExtenderImpl.java
-
BokehPreviewExtenderImpl.java
-
advanced/BokehAdvancedExtenderImpl.java
Классы расширения Night (реализуйте их, если поддерживается расширение Night)
-
NightImageCaptureExtenderImpl.java
-
NightPreviewExtenderImpl.java
-
advanced/NightAdvancedExtenderImpl.java
Классы автоматического расширения (реализуйте их, если поддерживается автоматическое расширение)
-
AutoImageCaptureExtenderImpl.java
-
AutoPreviewExtenderImpl.java
-
advanced/AutoAdvancedExtenderImpl.java
Классы расширения HDR (реализуйте их, если поддерживается расширение HDR)
-
HdrImageCaptureExtenderImpl.java
-
HdrPreviewExtenderImpl.java
-
advanced/HdrAdvancedExtenderImpl.java
Классы расширения Face Retouch (реализуйте его, если расширение Face Retouch поддерживается)
-
BeautyImageCaptureExtenderImpl.java
-
BeautyPreviewExtenderImpl.java
-
advanced/BeautyAdvancedExtenderImpl.java
Утилиты (необязательно, можно удалить)
-
advanced/Camera2OutputConfigImplBuilder.java
-
advanced/Camera2SessionConfigImplBuilder.java
Вам не обязательно предоставлять реализацию для каждого расширения. Если вы не реализуете расширение, установите isExtensionAvailable()
для возврата false
или удалите соответствующие классы Extender. API расширений Camera2 и CameraX сообщают приложению, что расширение недоступно.
Давайте рассмотрим, как API Camera2 и CameraX Extensions взаимодействуют с библиотекой поставщика для включения расширения. Следующая диаграмма иллюстрирует сквозной поток на примере расширения Night:
Рисунок 2. Реализация ночного расширения
Проверка версии:
Camera2/X вызывает
ExtensionVersionImpl.checkApiVersion()
, чтобы убедиться, что версияextensions-interface
реализованная OEM, совместима с поддерживаемыми версиями Camera2/X.Инициализация библиотеки поставщика:
InitializerImpl
имеет методinit()
, который инициализирует библиотеку поставщика. Camera2/X завершает инициализацию перед доступом к классам Extender.Классы Instantiate Extender:
Создает экземпляры классов Extender для расширения. Существует два типа Extender: Basic Extender и Advanced Extender. Необходимо реализовать один тип Extender для всех Extensions. Для получения дополнительной информации см. Basic Extender против Advanced Extender .
Camera2/X создает экземпляры классов Extender и взаимодействует с ними для извлечения информации и включения расширения. Для заданного расширения Camera2/X может создавать экземпляры классов Extender несколько раз. В результате не выполняйте тяжелую инициализацию в конструкторе или вызове
init()
. Выполняйте тяжелую работу только перед началом сеанса камеры, например, когда вызываетсяonInit()
в Basic Extender илиinitSession()
в Advanced Extender.Для расширения Night создаются следующие классы Extender для типа Basic Extender:
-
NightImageCaptureExtenderImpl.java
-
NightPreviewExtenderImpl.java
А для типа Advanced Extender:
-
NightAdvancedExtenderImpl.java
-
Проверить доступность расширения:
Перед включением расширения
isExtensionAvailable()
проверяет, доступно ли расширение для указанного идентификатора камеры через экземпляр Extender.Инициализируйте расширитель с информацией о камере:
Camera2/X вызывает
init()
для экземпляра Extender и передает ему идентификатор камеры иCameraCharacteristics
.Запрос информации:
Вызывает класс Extender для получения информации, такой как поддерживаемые разрешения, по-прежнему фиксирует предполагаемую задержку и захватывает ключи запроса от Extender в рамках подготовки к включению расширения.
Включить расширение на Extender:
Класс Extender предоставляет все интерфейсы, необходимые для включения класса. Он предлагает механизм для подключения OEM-реализации к конвейеру Camera2, например, для внедрения параметров запроса захвата или включения постпроцессора.
Для типа Advanced Extender Camera2/X взаимодействует с
SessionProcessorImpl
для включения расширения. Camera2/X извлекает экземплярSessionProcessorImpl
, вызываяcreateSessionProcessor()
в Extender.
В следующих разделах процесс расширения описывается более подробно.
Проверка версии
При загрузке библиотеки OEM-поставщика с устройства во время выполнения Camera2/X проверяет, совместима ли библиотека с версией extensions-interface
. extensions-interface
использует семантическое управление версиями, или MAJOR.MINOR.PATCH, например, 1.1.0 или 1.2.0. Однако во время проверки версий используются только major и minor версии.
Для проверки версии Camera2/X вызывает ExtensionVersionImpl.checkApiVersion()
с поддерживаемой версией extensions-interface
. Затем Camera2/X использует версию, сообщенную библиотекой OEM, чтобы определить, можно ли включить расширение и какие возможности оно должно вызывать.
Совместимость с основными версиями
Если основные версии интерфейса расширения Camera2/X и библиотеки поставщика различаются, то расширение считается несовместимым и отключается.
Обратная совместимость
Пока основная версия идентична, Camera2/X обеспечивает обратную совместимость с библиотеками OEM-поставщиков, созданными с предыдущими версиями extensions-interface
. Например, если Camera2/X поддерживает extensions-interface
1.3.0, библиотеки OEM-поставщиков, которые реализовали 1.0.0, 1.1.0 и 1.2.0, по-прежнему совместимы. Это также означает, что после реализации определенной версии библиотеки поставщика Camera2/X обеспечивает обратную совместимость библиотеки с будущими версиями extension-interface
.
Совместимость с предыдущими версиями
Прямая совместимость с библиотеками поставщиков новых extensions-interface
зависит от вас, OEM. Если вам нужны некоторые функции для реализации расширений, вы можете включить расширения, начиная с определенной версии. В этом случае вы можете вернуть поддерживаемую версию extensions-interface
, когда версия библиотеки Camera2/X соответствует требованиям. Если версии Camera2/X не поддерживаются, вы можете вернуть несовместимую версию, например 99.0.0, чтобы отключить расширения.
Инициализация библиотеки поставщика
После проверки версии extensions-interface
реализованной библиотекой OEM, Camera2/X начинает процесс инициализации. Метод InitializerImpl.init()
сигнализирует библиотеке OEM, что приложение пытается использовать расширения.
Camera2/X не выполняет никаких других вызовов в библиотеку OEM (кроме проверки версии) до тех пор, пока библиотека поставщика OEM не вызовет OnExtensionsInitializedCallback.onSuccess()
для уведомления о завершении инициализации.
Необходимо реализовать InitializerImpl
с extensions-interface
1.1.0. Camera2/X пропускает этап инициализации библиотеки, если библиотека поставщика OEM реализует extensions-interface
1.0.0.
Базовый удлинитель против расширенного удлинителя
Существует два типа реализации extensions-interface
: Basic Extender и Advanced Extender. Advanced Extender поддерживается с версии extensions-interface
1.2.0.
Реализуйте базовый расширитель для расширений, которые обрабатывают изображения в HAL камеры или используют постпроцессор, способный обрабатывать потоки YUV.
Реализуйте Advanced Extender для расширений, которым необходимо настраивать конфигурацию потока Camera2 и отправлять запросы на захват по мере необходимости.
Для сравнения смотрите следующую таблицу:
Базовый удлинитель | Расширенный удлинитель | |
---|---|---|
Конфигурации потока | Зафиксированный Предварительный просмотр: PRIVATE или YUV_420_888 (если процессор существует)Фотоснимок: JPEG или YUV_420_888 (если есть процессор) | Возможность настройки OEM-производителем. |
Отправка запроса на захват | Только Camera2/X может отправлять запросы на захват. Вы можете задать параметры для этих запросов. Когда процессор предоставляется для захвата изображения, Camera2/X может отправлять несколько запросов на захват и отправлять все изображения и результаты захвата процессору. | Экземпляр RequestProcessorImpl предоставляется вам для выполнения запроса захвата камеры2 и получения результатов и изображения. Camera2/X вызывает |
Крючки в трубопроводе камеры |
|
|
Подходит для | Расширения, реализованные в HAL камеры или в процессоре, обрабатывающем изображения YUV. |
|
Поддерживаемая версия 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 | val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...) |
Базовый удлинитель
Интерфейс Basic Extender обеспечивает хуки в нескольких местах в конвейере камеры. Каждый тип расширения имеет соответствующие классы Extender, которые OEM-производителям необходимо реализовать.
В следующей таблице перечислены классы расширителей, которые OEM-производителям необходимо реализовать для каждого расширения:
Реализуемые классы-расширители | |
---|---|
Ночь | NightPreviewExtenderImpl.java |
HDR | HdrPreviewExtenderImpl.java |
Авто | AutoPreviewExtenderImpl.java |
Боке | BokehPreviewExtenderImpl.java |
Ретушь лица | BeautyPreviewExtenderImpl.java |
В следующем примере мы используем PreviewExtenderImpl
и ImageCaptureExtenderImpl
в качестве заполнителей. Замените их именами реальных файлов, которые вы реализуете.
Basic Extender имеет следующие возможности:
- Внедрите параметры сеанса при настройке
CameraCaptureSession
(onPresetSession
). - Уведомляет вас о событиях начала и закрытия сеанса захвата и отправляет один запрос на уведомление HAL с возвращаемыми параметрами (
onEnableSession
,onDisableSession
). - Внедрите параметры захвата для запроса (
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - Добавьте процессоры для предварительного просмотра и захвата неподвижных изображений, способные обрабатывать поток
YUV_420_888
.
Давайте посмотрим, как Camera2/X вызывает extensions-interface
для реализации трех потоков приложений, упомянутых выше.
Поток приложения 1: проверка доступности расширения
Рисунок 3. Поток приложения 1 на базовом расширителе
В этом потоке Camera2/X напрямую вызывает метод isExtensionAvailable()
как PreviewExtenderImpl
, так и ImageCaptureExtenderImpl
без вызова init()
. Оба класса Extender должны возвращать true
для включения расширений.
Это часто первый шаг для приложений, чтобы проверить, поддерживается ли данный тип расширения для данного идентификатора камеры, прежде чем включать расширение. Это связано с тем, что некоторые расширения поддерживаются только для определенных идентификаторов камеры.
Поток приложения 2: Запрос информации
Рисунок 4. Поток приложения 2 на базовом расширителе
Определив, доступно ли расширение, приложения должны запросить следующую информацию, прежде чем включать расширение.
Диапазон задержки захвата неподвижного изображения:
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
возвращает диапазон задержки захвата, чтобы приложение могло оценить, целесообразно ли включать расширение для текущего сценария.Поддерживаемые размеры для поверхности предварительного просмотра и захвата:
ImageCaptureExtenderImpl.getSupportedResolutions
иPreviewExtenderImpl.getSupportedResolutions
возвращают список форматов изображений и размеров, поддерживаемых для формата и размера поверхности.Поддерживаемые ключи запроса и результата: Camera2/X вызывает следующие методы для извлечения поддерживаемых ключей запроса захвата и ключей результата из вашей реализации:
-
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
-
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
-
Camera2/X всегда сначала вызывает init()
для этих классов Extender, прежде чем запрашивать дополнительную информацию.
Поток приложения 3: Предварительный просмотр/захват неподвижного изображения с включенным расширением (реализация HAL)
Рисунок 5. Поток приложения 3 на базовом расширителе
На приведенной выше схеме показан основной поток включения предварительного просмотра и захвата неподвижных изображений с расширением без процессора. Это означает, что HAL камеры обрабатывает расширение.
В этом потоке Camera2/X сначала вызывает init()
, а затем onInit
, который уведомляет вас о том, что сеанс камеры вот-вот начнется с указанными расширениями. Вы можете выполнить тяжелую инициализацию в onInit()
.
При настройке CameraCaptureSession
Camera2/X вызывает onPresetSession
для получения параметров сеанса. После успешной настройки сеанса захвата Camera2/X вызывает onEnableSession
, возвращая экземпляр CaptureStageImpl
, содержащий параметры захвата. Camera2/X немедленно отправляет один запрос с этими параметрами захвата, чтобы уведомить HAL. Аналогично, перед закрытием сеанса захвата Camera2/X вызывает onDisableSession
, а затем отправляет один запрос с возвращенными параметрами захвата.
Повторяющийся запрос, вызванный Camera2/X, содержит параметры запроса, возвращаемые PreviewExtenderImpl.getCaptureStage()
. Кроме того, запрос на захват неподвижного изображения содержит параметры, возвращаемые ImageCaptureExtenderImpl.getCaptureStages()
.
Наконец, Camera2/X вызывает onDeInit()
после завершения сеанса камеры. Вы можете освободить ресурсы в onDeinit()
.
Процессор предварительного просмотра
Помимо HAL камеры, можно также реализовать расширения в процессоре.
Реализуйте PreviewExtenderImpl.getProcessorType
, чтобы указать тип процессора, как описано ниже:
PROCESSOR_TYPE_NONE
: Нет процессора. Изображения обрабатываются в HAL камеры.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY
: тип процессора позволяет обновлять повторяющийся запрос новыми параметрами запроса захвата на основе последнегоTotalCaptureResult
.PreviewExtenderImpl.getProcessor
должен возвращать экземплярRequestUpdateProcessorImpl
, который обрабатывает экземплярTotalCaptureResult
и возвращает экземплярCaptureStageImpl
для обновления повторяющегося запроса.PreviewExtenderImpl.getCaptureStage()
также должен отражать результат обработки и возвращать последнийCaptureStageImpl
.PROCESSOR_TYPE_IMAGE_PROCESSOR
: этот тип позволяет реализовать процессор для обработки изображенийYUV_420_888
и записи вывода наPRIVATE
поверхность.Вам необходимо реализовать и вернуть экземпляр
PreviewImageProcessorImpl
вPreviewExtenderImpl.getProcessor
. Процессор отвечает за обработку входных изображенийYUV_420_888
. Он должен записывать выходные данные в форматPRIVATE
предварительного просмотра. Camera2/X использует поверхностьYUV_420_888
вместоPRIVATE
для настройкиCameraCaptureSession
для предварительного просмотра.Смотрите следующую иллюстрацию для потока:
Рисунок 6. Поток предварительного просмотра с помощью PreviewImageProcessorImpl
Интерфейс PreviewImageProcessorImpl
расширяет ProcessImpl
и имеет три важных метода:
onOutputSurface(Surface surface, int imageFormat)
устанавливает выходную поверхность для процессора. ДляPreviewImageProcessorImpl
imageFormat
— это формат пикселей, напримерPixelFormat.RGBA_8888
.onResolutionUpdate(Size size)
устанавливает размер входного изображения.onImageFormatUpdate(int imageFormat)
устанавливает формат входного изображения. В настоящее время это может быть толькоYUV_420_888
.
Процессор захвата изображений
Для захвата неподвижных изображений можно реализовать процессор, вернув экземпляр CaptureProcessorImpl
с помощью ImageCaptureExtenderImpl.getCaptureProcessor
. Процессор отвечает за обработку списка захваченных изображений YUV_420_888
и экземпляров TotalCaptureResult
и запись вывода на поверхность YUV_420_888
.
Вы можете с уверенностью предположить, что предварительный просмотр включен и работает, прежде чем отправлять запрос на захват неподвижного изображения.
Смотрите поток на схеме ниже:
Рисунок 7. Поток захвата с помощью CaptureProcessorImpl
Camera2/X использует формат поверхности
YUV_420_888
для захвата неподвижных изображений, чтобы настроить сеанс захвата. Camera2/X подготавливаетCaptureProcessorImpl
, вызывая:-
CaptureProcessorImpl.onImageFormatUpdate()
сYUV_420_888
. -
CaptureProcessorImpl.onResolutionUpdate()
с размером входного изображения. -
CaptureProcessorImpl.onOutputSurface()
с выходной поверхностьюYUV_420_888
.
-
ImageCaptureExtenderImpl.getCaptureStages
возвращает списокCaptureStageImpl
, где каждый элемент сопоставляется с экземпляромCaptureRequest
с параметрами захвата, которые отправляются Camera2/X. Например, если он возвращает список из трех экземпляровCaptureStageImpl
, Camera2/X отправляет три запроса захвата с соответствующими параметрами захвата, используя APIcaptureBurst
.Полученные изображения и экземпляры
TotalCaptureResult
объединяются и отправляются вCaptureProcessorImpl
для обработки.CaptureProcessorImpl
записывает результирующее изображение (форматYUV_420_888
) на выходную поверхность, указанную вызовомonOutputSurface()
. Camera2/X при необходимости преобразует его в изображения JPEG.
Поддержка ключей и результатов запроса захвата
В дополнение к предварительному просмотру и захвату камеры, приложения могут устанавливать масштабирование, параметры вспышки или активировать функцию фокусировки по нажатию. Эти параметры могут быть несовместимы с реализацией вашего расширения.
В extensions-interface
1.3.0 были добавлены следующие методы, позволяющие вам раскрывать параметры, поддерживаемые вашей реализацией:
-
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
возвращает ключи запроса захвата, поддерживаемые вашей реализацией. -
ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
возвращает ключи результата захвата, содержащиеся в результате захвата.
Если HAL камеры обрабатывает расширение, Camera2/X извлекает результаты захвата в CameraCaptureSession.CaptureCallback
. Однако, если процессор реализован, Camera2/X извлекает результаты захвата в ProcessResultImpl
, который передается методу process()
в PreviewImageProcessorImpl
и CaptureProcessorImpl
. Вы несете ответственность за сообщение результата захвата через ProcessResultImpl
в Camera2/X.
См. определение интерфейса CaptureProcessorImpl
ниже в качестве примера. В extensions-interface
1.3.0 или выше вызывается второй вызов process()
:
Interface CaptureProcessorImpl extends ProcessorImpl {
// invoked when extensions-interface version < 1.3.0
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
// invoked when extensions-interface version >= 1.3.0
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor);
}
Для обычных операций с камерой, таких как масштабирование, фокусировка по касанию, вспышка и компенсация экспозиции, мы рекомендуем поддерживать следующие клавиши как для запроса на захват, так и для результата захвата:
- Увеличить:
-
CaptureRequest#CONTROL_ZOOM_RATIO
-
CaptureRequest#SCALER_CROP_REGION
-
- Фокусировка нажатием:
-
CaptureRequest#CONTROL_AF_MODE
-
CaptureRequest#CONTROL_AF_TRIGGER
-
CaptureRequest#CONTROL_AF_REGIONS
-
CaptureRequest#CONTROL_AE_REGIONS
-
CaptureRequest#CONTROL_AWB_REGIONS
-
- Вспышка:
-
CaptureRequest#CONTROL_AE_MODE
-
CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
-
CaptureRequest#FLASH_MODE
-
- Компенсация экспозиции:
-
CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
-
Для базовых расширителей, реализующих 1.2.0 или более ранние версии, API расширений CameraX явно поддерживает все указанные выше ключи. Для extensions-interface
1.3.0 и CameraX, и Camera2 учитывают возвращенный список и поддерживают только содержащиеся в нем ключи. Например, если вы решили возвращать только CaptureRequest#CONTROL_ZOOM_RATIO
и CaptureRequest#SCALER_CROP_REGION
в реализации 1.3.0, то это означает, что для приложения поддерживается только зум, а фокусировка касанием, вспышка и компенсация экспозиции не допускаются.
Расширенный удлинитель
Advanced Extender — это тип реализации поставщика на основе API Camera2. Этот тип Extender был добавлен в extensions-interface
1.2.0. В зависимости от производителя устройства расширения могут быть реализованы на уровне приложения, что зависит от следующих факторов:
Пользовательская конфигурация потока: настройте пользовательские потоки, такие как поток RAW, или используйте несколько потоков для разных идентификаторов физических камер.
Возможность отправки запросов Camera2: поддержка сложной логики взаимодействия, которая может отправлять запросы захвата с параметрами, основанными на результатах предыдущих запросов.
Advanced Extender предоставляет оболочку или промежуточный уровень, позволяющий настраивать конфигурацию потока и отправлять запросы на захват по требованию.
Файлы для реализации
Для переключения на реализацию Advanced Extender метод isAdvancedExtenderImplemented()
в ExtensionVersionImpl
должен возвращать true
. Для каждого типа расширения OEM-производители должны реализовать соответствующие классы Extender. Файлы реализации Advanced Extender находятся в расширенном пакете.
Реализуемые классы-расширители | |
---|---|
Ночь | advanced/NightAdvancedExtenderImpl.java |
HDR | advanced/HdrAdvancedExtenderImpl.java |
Авто | advanced/AutoAdvancedExtenderImpl.java |
Боке | advanced/BokehAdvancedExtenderImpl.java |
Ретушь лица | advanced/BeautyAdvancedExtenderImpl.java |
В следующем примере мы используем AdvancedExtenderImpl
в качестве заполнителя. Замените его на имя файла Extender для расширения, которое вы реализуете.
Давайте посмотрим, как Camera2/X вызывает extensions-interface
для реализации трех потоков приложения.
Поток приложения 1: проверка доступности расширений
Рисунок 8. Поток приложения 1 на Advanced Extender
Сначала приложение проверяет, поддерживается ли данное расширение.
Поток приложения 2: Запрос информации
Рисунок 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: предварительный просмотр/захват неподвижного изображения с включенным расширением
Рисунок 10. Поток приложения 3 на Advanced Extender
На диаграмме выше показан основной поток для запуска предварительного просмотра и захвата неподвижного изображения для типа Advanced Extender. Давайте рассмотрим каждый шаг.
Экземпляр
SessionProcessorImpl
Основная реализация Advanced Extender находится в
SessionProcessorImpl
, который отвечает за предоставление настраиваемой конфигурации сеанса и отправку запросов захвата для инициирования предварительного просмотра и запроса на неподвижный захват.AdvancedExtenderImpl.createSessionProcessor()
вызывается для возврата экземпляраSessionProcessorImpl
.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
.-
onCaptureSessionStart
иRequestProcessorImpl
Когда запускается
CameraCaptureSession
и фреймворк Camera вызываетonConfigured()
, то Camera2/X вызываетSessionProcessorImpl.onCaptureSessionStart()
с оболочкой запроса Camera2RequestProcessImpl
. Camera2/X реализуетRequestProcessImpl
, что позволяет выполнять запросы захвата и извлекать изображения , если используетсяImageReaderOutputConfigImpl
.API
RequestProcessImpl
аналогичны API Camera2CameraCaptureSession
с точки зрения выполнения запросов. Различия следующие:- Целевая поверхность указывается идентификатором экземпляра
Camera2OutputConfigImpl
. - Возможность извлечения изображения из
ImageReader
.
Вы можете вызвать
RequestProcessorImpl.setImageProcessor()
с указанным идентификаторомCamera2OutputConfigImpl
, чтобы зарегистрировать экземплярImageProcessorImpl
для получения изображений.Экземпляр
RequestProcessImpl
становится недействительным после того, как Camera2/X вызываетSessionProcessorImpl.onCaptureSessionEnd()
.- Целевая поверхность указывается идентификатором экземпляра
Запустите предварительный просмотр и сделайте снимок
В реализации 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
.-
startTrigger
SessionProcessorImpl.startTrigger()
вызывается для запуска триггера, такого какCaptureRequest.CONTROL_AF_TRIGGER
иCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
. Вы можете игнорировать любые ключи запроса захвата, которые не были объявлены вAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
.startTrigger()
поддерживается сextensions-interface
1.3.0. Он позволяет приложениям реализовывать фокусировку по нажатию и вспышку с расширениями.Очистить
При завершении сеанса захвата
SessionProcessorImpl.onCaptureSessionEnd()
вызывается перед закрытиемCameraCaptureSession
. После закрытия сеанса захватаdeInitSession()
выполняет очистку.
Поддержка предварительного просмотра, захвата стоп-кадров и анализа изображений
Вам следует применить расширение для обоих вариантов использования: предпросмотра и захвата неподвижных изображений. Однако, если задержка слишком велика для плавного отображения предпросмотра, вы можете применить расширение только для захвата неподвижных изображений.
Для основного типа Extender, независимо от того, чтобы включить расширение для предварительного просмотра, вы должны реализовать как ImageCaptureExtenderImpl
, так и PreviewExtenderImpl
для данного расширения. Часто в приложении также используется поток YUV для анализа содержимого изображения, например, поиск QR -кодов или текста. Чтобы лучше поддерживать этот вариант использования, вы должны поддерживать комбинацию потока предварительного просмотра, все еще захвата и потока YUV_420_888
для настройки CameraCaptureSession
. Это означает, что если вы реализуете процессор, вам нужно поддерживать комбинацию потока трех потоков YUV_420_888
.
Для Advanced Extender Camera2/X передает три выходных поверхностей на вызов SessionProcessorImpl.initSession()
. Эти выходные поверхности предназначены для предварительного просмотра, все еще захвата и анализа изображений соответственно. Вы должны убедиться, что предварительный просмотр и до сих пор захватывают выходные поверхности, показывают действительный вывод. Однако для выходной поверхности анализа изображения убедитесь, что она работает только тогда, когда она не ноль. Если ваша реализация не может поддержать поток анализа изображений, вы можете вернуть пустой список в AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
. Это гарантирует, что выходная поверхность анализа изображений всегда нулевой в SessionProcessorImpl.initSession()
.
Поддержка захвата видео
Текущая архитектура расширения камеры поддерживает только предварительный просмотр и до сих пор захватывает варианты использования. Мы не поддерживаем включение расширения на поверхностях MediaCodec
или MediaRecorder
для записи видео. Тем не менее, приложения могут записать вывод предварительного просмотра.
Поддержка поверхностей MediaCodec
и MediaRecorder
находится под следствием.
Специфичные для расширения метаданные
Для Android 14 и выше, специфичные для расширения метаданные позволяют клиентам по расширению камеры устанавливать и получать настройки и результаты запроса на расширение и получать. В частности, клиенты расширения камеры могут использовать параметр запроса захвата EXTENSION_STRENGTH
для управления прочностью расширения и результат захвата EXTENSION_CURRENT_TYPE
, чтобы указать включенный тип расширения.
Запросы на захват
Параметр запроса захвата EXTENSION_STRENGTH
контролирует силу эффекта постобработки расширения. Соответствующий результат захвата включает значение прочности по умолчанию, если этот параметр не установлен явно клиентом. Этот параметр может быть применен следующим образом для этих типов расширения:
-
BOKEH
: контролирует количество размытия. -
HDR
иNIGHT
: управляет количеством слитых изображений и яркостью конечного изображения. -
FACE_RETOUCH
: контролирует количество косметического улучшения и сглаживания кожи.
Поддерживаемый диапазон для параметра EXTENSION_STRENGTH
составляет от 0
до 100
, а 0
указывает на обработку удлинения или простую пропуск и 100
указывающие максимальную прочность на удлинение эффекта обработки.
Чтобы добавить поддержку для EXTENSION_STRENGTH
, используйте API -интерфейсы специфических параметров поставщика, представленные в версии 1.3.0 интерфейса библиотеки расширения. Для получения дополнительной информации см. getAvailableCaptureRequestKeys()
.
Захват результаты
Результат захвата EXTENSION_CURRENT_TYPE
Let Enginations уведомляет клиентов о типе активного расширения.
Поскольку расширения, использующие AUTO
тип динамического переключения между типами расширения, такими как HDR
и NIGHT
в зависимости от условий сцены, приложения расширения камеры могут использовать EXTENSION_CURRENT_TYPE
для отображения информации о текущем расширении, выбранном AUTO
Extension.
В реальном времени по-прежнему оценить оценку задержки
Для Android 14 и выше клиенты по расширению камеры могут запросить в режиме реального времени оценки задержки на основе сцены и условий окружающей среды с использованием getRealtimeStillCaptureLatency()
. Этот метод обеспечивает более точные оценки, чем статический метод getEstimatedCaptureLatencyRangeMillis()
метод. Основываясь на оценке задержки, приложения могут решить пропустить обработку расширения или отобразить указание, чтобы уведомлять пользователей о долгосрочной операции.
CameraExtensionSession.StillCaptureLatency latency;
latency = extensionSession.getRealtimeStillCaptureLatency();
// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().
latency.getCaptureLatency();
// The processing latency from ExtensionCaptureCallback#onCaptureProcessStarted() until the processed frame returns to the client.
latency.getProcessingLatency();
Для поддержки в режиме реального времени все еще захватывают оценки задержки, реализуйте следующее:
- Основные расширения:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Расширенные расширения:
SessionProcessorImpl.getRealtimeCaptureLatency
Захват обработки обработки прогресса
Для 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
}
}
…
}
Чтобы поддержать обратные вызовы обработки обработки захвата, реализация вашего поставщика расширения должна вызвать следующие обратные вызовы с текущим значением прогресса:
- Основные расширения:
ProcessResultImpl.onCaptureProcessProgressed()
- Усовершенствованные расширения:
CaptureCallback.onCaptureProcessProgressed()
Пост -просмотр по -прежнему захват
Для 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();
…
}
Для поддержки пост -просмотра по -прежнему захват, реализация вашего поставщика должна реализовать следующее:
Основные расширения:
CaptureProcessorImpl.onPostviewOutputSurface
иCaptureProcessorImpl.processWithPostview
Расширенные расширения:
SessionProcessorImpl.startCaptureWithPostview
Поддержка SurfaceView выход
Для Android 14 и выше клиенты по расширению камеры могут использовать пути для оптимизированного предварительного просмотра мощности и производительности, зарегистрировав экземпляр SurfaceView
для предварительного просмотра вывода для повторных запросов.
Для поддержки выхода SurfaceView
ваш реализация расширения поставщика должна быть способна потоковой передаче и выводу предварительного просмотра в экземпляры SurfaceView
. Чтобы убедиться, что это поддерживается, запустите модуль SurfaceViewExtensionPreviewTest.java
CTS.
Типы сеансов конкретных поставщиков
Функция позволяет реализациям расширения поставщиков выбирать тип сеанса конкретного поставщика, который будет установлен во внутреннем сеансе захвата камеры вместо значения по умолчанию.
Функция полностью работает в рамках и стеке поставщиков и не имеет видимого воздействия API клиента/общественности.
Чтобы выбрать тип сеанса, специфичный для поставщика, реализуйте следующее для ваших библиотек расширения: * ExtenderStateListener.onSessionType()
для основных расширений * Camera2SessionConfigImpl.getSessionType()
для расширенных расширений
История версии интерфейса расширений
В следующей таблице показана история версии интерфейса расширения камеры. Вы всегда должны реализовать библиотеку поставщиков с последней версией.
Версия | Добавлены функции |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
Референтная реализация
Следующие справочные реализации библиотеки OEM -поставщиков доступны в frameworks/ex
.
advancedSample
: базовая реализация Advanced Extender.sample
: базовая реализация основного удлинителя.service_based_sample
: реализация, которая демонстрирует, как размещать расширения камеры вService
. Эта реализация содержит следующие компоненты:oem_library
: API API API-Extensions-Interface
. Это действует как проход, который пересылает вызовы отExtensions-Interface
в сервис. Эта библиотека также предоставляет файлы AIDL и классы обертки для связи с службой.Advanced Extender включен по умолчанию. Чтобы включить базовый удлинитель, измените
ExtensionsVersionImpl#isAdvancedExtenderImplemented
чтобы вернутьfalse
.extensions_service
: образец реализации службы расширений. Добавьте свою реализацию здесь. Интерфейс для реализации в службе аналогиченExtensions-Interface
. Например, реализацияIAdvancedExtenderImpl.Stub
выполняет те же операции, что иAdvancedExtenderImpl
.ImageWrapper
иTotalCaptureResultWrapper
должны сделатьImage
иTotalCaptureResult
.
Установите библиотеку поставщиков на устройстве
Библиотека поставщиков OEM не встроена в приложение; Он загружен с устройства во время выполнения Camera2/X. В Camerax библиотека <uses-library>
, которая определена в файле androidx.camera.extensions.impl
, которая определяется в файле AndroidManifest.xml
, которая должна быть загружена. В Camera2 фреймворк загружает службу camera-extensions
, которая также заявляет, что <uses-library>
библиотека <использует> библиотеку androidx.camera.extensions.impl
во время выполнения.
Это позволяет сторонним приложениям, используя расширения для автоматической загрузки библиотеки поставщиков OEM. Библиотека OEM отмечена необязательной, поэтому приложения могут работать на устройствах, у которых нет библиотеки на устройстве. Camera2/X обрабатывает это поведение автоматически, когда приложение пытается использовать расширение камеры, если производитель устройств помещает библиотеку OEM на устройство, чтобы его можно было обнаружить приложением.
Чтобы настроить библиотеку OEM на устройстве, сделайте следующее:
- Добавьте файл разрешений, который требуется тегом
<uses-library>
, используя следующий формат:/etc/permissions/ ANY_FILENAME .xml
. Например,/etc/permissions/camera_extensions.xml
. Файлы в этом каталоге предоставляют сопоставление библиотеки, названной в<uses-library>
на фактический путь файла на устройстве. Используйте пример ниже, чтобы добавить необходимую информацию в файл.
-
name
должно бытьandroidx.camera.extensions.impl
, так как это библиотека, которую ищет камера. -
file
- это абсолютный путь файла, который содержит реализацию расширений (например,/system/framework/androidx.camera.extensions.impl.jar
).
<?xml version="1.0" encoding="utf-8"?> <permissions> <library name="androidx.camera.extensions.impl" file="OEM_IMPLEMENTED_JAR" /> </permissions>
-
В Android 12 или выше устройства, поддерживающие расширения камеры, должны иметь свойство ro.camerax.extensions.enabled
, установленное в true
, что позволяет запрашивать, поддерживает ли устройство расширения. Для этого добавьте следующую строку в файл, создайте файл:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Проверка
Чтобы проверить вашу реализацию библиотеки OEM-поставщиков на этапе разработки, используйте пример приложения на androidx-main/camera/integration-tests/extensionstestapp/
, которое проходит через различные расширения поставщиков.
После того, как вы завершите свою реализацию, используйте инструмент проверки расширений камеры для запуска автоматизированных и ручных тестов, чтобы убедиться, что библиотека поставщиков реализована правильно.
Расширенный режим сцены по сравнению с расширениями камеры
Для расширения Bokeh, в дополнение к тому, что он вызывает его с помощью расширений камеры, вы можете выявить расширение, используя расширенный режим сцены, который включен через клавишу CONTROL_EXTENDED_SCENE_MODE
. Для получения дополнительной информации о реализации см. Camera Bokeh .
Режим расширенной сцены имеет меньше ограничений по сравнению с расширениями камеры для приложений Camera2. Например, вы можете включить расширенный режим сцены в обычном экземпляре CameraCaptureSession
, который поддерживает гибкие комбинации потока и параметры запроса захвата. Напротив, расширения камеры поддерживают только фиксированный набор типов потоков и имеют ограниченную поддержку для параметров запроса захвата.
Недостатком расширенного режима сцены является то, что вы можете реализовать его только в камере HAL, что означает, что он должен быть проверен для работы на всех ортогональных элементах управления, доступных для разработчиков приложений.
Мы рекомендуем разоблачить Боке, используя как расширенный режим сцены, так и расширения камеры, потому что приложения могут предпочесть использовать конкретный API для включения BOKEH. Мы рекомендуем сначала использовать расширенный режим сцены, потому что это наиболее гибкий способ для приложений, чтобы включить расширение Bokeh. Затем вы можете реализовать интерфейс расширения камеры на основе расширенного режима сцены. Если внедрить Bokeh в камере HAL сложна, например, поскольку для обработки изображений для обработки изображений для обработки изображений требуется пост -процессор, работающий на уровне приложения.
Часто задаваемые вопросы (FAQ)
Есть ли какие -либо ограничения на уровни API?
Да Это зависит от набора функций API Android, который требуется реализацией библиотеки OEM -поставщиков. Например, ExtenderStateListener.onPresetSession()
использует вызов SessionConfiguration.setSessionParameters()
для набора базового набора тегов. Этот вызов доступен только на уровне API 28 и выше. Для получения подробной информации о конкретных методах интерфейса см. Справочную документацию API .