Производители устройств могут предоставлять специальные эффекты, такие как боке, ночной режим и HDR, сторонним разработчикам через интерфейс Camera Extensions, предоставляемый библиотекой OEM-поставщика. Разработчики могут использовать API Camera2 Extensions и CameraX Extensions для включения эффектов, которые реализованы как расширения в библиотеке OEM-поставщика на устройстве.
Список поддерживаемых расширений, одинаковый для Camera2 и CameraX, см. в разделе CameraX Extensions API . Если вы хотите добавить расширение, сообщите об ошибке здесь .
На этой странице описывается, как внедрить и включить библиотеку OEM-поставщика на устройствах.
Архитектура
Следующая диаграмма описывает архитектуру интерфейса Camera Extensions или extensions-interface
:
Рис. 1. Схема архитектуры Camera Extensions
Как показано на диаграмме, для поддержки расширений камеры необходимо реализовать extensions-interface
предоставляемый библиотекой OEM-поставщика. Ваша библиотека поставщика OEM включает два API: CameraX Extensions API и Camera2 Extensions API , которые используются приложениями CameraX и Camera2 соответственно для доступа к расширениям поставщиков.
Внедрить библиотеку поставщиков OEM
Чтобы внедрить библиотеку OEM-поставщика, скопируйте файлы camera-extensions-stub
в проект системной библиотеки. Эти файлы определяют интерфейс Camera Extensions.
Файлы camera-extensions-stub
делятся на следующие категории:
Основные файлы интерфейса (не изменять)
-
PreviewExtenderImpl.java
-
ImageCaptureExtenderImpl.java
-
ExtenderStateListener.java
-
ProcessorImpl.java
-
PreviewImageProcessorImpl.java
-
CaptureProcessorImpl.java
-
CaptureStageImpl.java
-
RequestUpdateProcessorImpl.java
-
ProcessResultImpl.java
-
advanced/AdvancedExtenderImpl.java
-
advanced/Camera2OutputConfigImpl.java
-
advanced/Camera2SessionConfigImpl.java
-
advanced/ImageProcessorImpl.java
-
advanced/ImageReaderOutputConfigImpl.java
-
advanced/ImageReferenceImpl.java
-
advanced/MultiResolutionImageReaderOutputConfigImpl.java
-
advanced/OutputSurfaceImpl.java
-
advanced/RequestProcessorImpl.java
-
advanced/SessionProcessorImpl.java
-
advanced/SurfaceOutputConfigImpl.java
Обязательные реализации (добавьте свою реализацию)
-
ExtensionVersionImpl.java
-
InitializerImpl.java
Классы расширения Bokeh (реализуйте его, если расширение Bokeh поддерживается)
-
BokehImageCaptureExtenderImpl.java
-
BokehPreviewExtenderImpl.java
-
advanced/BokehAdvancedExtenderImpl.java
Классы ночного расширения (реализуйте его, если поддерживается ночное расширение)
-
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
или удалите соответствующие классы-расширители. API расширений Camera2 и CameraX сообщают приложению, что расширение недоступно.
Давайте рассмотрим, как API расширений Camera2 и CameraX взаимодействуют с библиотекой поставщика, чтобы включить расширение. Следующая диаграмма иллюстрирует сквозной поток на примере ночного расширения:
Рисунок 2. Реализация ночного расширения
Проверка версии:
Camera2/X вызывает
ExtensionVersionImpl.checkApiVersion()
, чтобы убедиться, что версияextensions-interface
реализованная OEM, совместима с версиями, поддерживаемыми Camera2/X.Инициализация библиотеки поставщика:
У
InitializerImpl
есть методinit()
, который инициализирует библиотеку поставщика. Camera2/X завершает инициализацию перед доступом к классам Extender.Создание экземпляров классов-расширителей:
Создает экземпляры классов Extender для расширения. Существует два типа расширителя: базовый расширитель и расширенный расширитель. Вы должны реализовать один тип расширителя для всех расширений. Дополнительные сведения см. в разделе Базовый расширитель и Расширенный расширитель .
Camera2/X создает экземпляры классов Extender и взаимодействует с ними для получения информации и включения расширения. Для данного расширения Camera2/X может создавать экземпляры классов Extender несколько раз. Поэтому не выполняйте громоздкую инициализацию в конструкторе или вызове
init()
. Выполняйте тяжелую работу только перед началом сеанса камеры, например, когдаonInit()
в базовом расширителе илиinitSession()
в расширенном расширителе.Для ночного расширения создаются экземпляры следующих классов расширений для базового типа расширений:
-
NightImageCaptureExtenderImpl.java
-
NightPreviewExtenderImpl.java
И для типа Advanced Extender:
-
NightAdvancedExtenderImpl.java
-
Проверить наличие расширения:
Перед включением расширения
isExtensionAvailable()
проверяет, доступно ли расширение для указанного идентификатора камеры через экземпляр Extender.Инициализируйте расширитель информацией о камере:
Camera2/X вызывает
init()
экземпляра Extender и передает ему идентификатор камеры иCameraCharacteristics
.Информация о запросе:
Вызывает класс Extender для получения информации, такой как поддерживаемые разрешения, по-прежнему фиксирует предполагаемую задержку и получает ключи запросов от Extender в рамках подготовки к включению расширения.
Включите расширение на повторителе:
Класс Extender предоставляет все интерфейсы, необходимые для включения класса. Он предлагает механизм подключения OEM-реализации к конвейеру Camera2, например, ввод параметров запроса захвата или включение постпроцессора.
Для типа Advanced Extender Camera2/X взаимодействует с
SessionProcessorImpl
, чтобы включить расширение. Camera2/X извлекает экземплярSessionProcessorImpl
, вызываяcreateSessionProcessor()
в расширителе.
В следующих разделах процесс расширения описывается более подробно.
Проверка версии
При загрузке библиотеки поставщика 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 предоставляется вам для выполнения запроса захвата camera2 и получения результатов и изображения. Camera2/X вызывает |
Хуки в конвейере камеры |
|
|
Подходит для | Расширения реализованы в камере HAL или в процессоре, обрабатывающем изображения YUV. |
|
Поддерживаемая версия API | Расширения Camera2: Android T (экспериментальная версия AOSP) или выше CameraX Extensions: camera-extensions 1.1.0 или выше | Расширения Camera2: Android 12L или выше CameraX Extensions: camera-extensions 1.2.0-alpha03 или выше |
Потоки приложений
В следующей таблице показаны три типа потоков приложений и соответствующие им вызовы Camera Extensions 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, предварительный просмотр, ...) |
Базовый удлинитель
Интерфейс Basic Extender обеспечивает подключение к нескольким местам конвейера камеры. У каждого типа расширения есть соответствующие классы-расширители, которые должны реализовать OEM-производители.
В следующей таблице перечислены классы расширителей, которые OEMS должны реализовать для каждого расширения:
Классы-расширители для реализации | |
---|---|
Ночь | 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 в Basic Extender
В этом потоке Camera2/X напрямую вызывает метод isExtensionAvailable()
как PreviewExtenderImpl
, так и ImageCaptureExtenderImpl
без вызова init()
. Оба класса Extender должны возвращать значение true
, чтобы включить расширения.
Это часто является первым шагом для приложений, чтобы проверить, поддерживается ли данный тип расширения для данного идентификатора камеры, прежде чем включать расширение. Это связано с тем, что некоторые расширения поддерживаются только для определенных идентификаторов камер.
Поток приложения 2: запрос информации
Рис. 4. Поток приложения 2 в Basic Extender
Определив, доступно ли расширение, приложения должны запросить следующую информацию, прежде чем включать расширение.
Диапазон задержки захвата по- прежнему:
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
возвращает диапазон задержки захвата, чтобы приложение могло оценить, уместно ли включить расширение для текущего сценария.Поддерживаемые размеры для предварительного просмотра и захвата поверхности:
ImageCaptureExtenderImpl.getSupportedResolutions
иPreviewExtenderImpl.getSupportedResolutions
возвращают список форматов изображений и размеров, которые поддерживаются для формата и размера поверхности.Поддерживаемые ключи запроса и результата: Camera2/X вызывает следующие методы для извлечения поддерживаемых ключей запроса захвата и ключей результата из вашей реализации:
-
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
-
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
-
Camera2/X всегда сначала вызывает init()
для этих классов-расширителей, прежде чем запрашивать дополнительную информацию.
Поток приложения 3: Предварительный просмотр/неподвижный захват с включенным расширением (реализация HAL)
Рис. 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
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 отправляет три запроса на захват с соответствующими параметрами захвата с использованием API-интерфейсаcaptureBurst
.Полученные изображения и экземпляры
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 — это тип реализации поставщика, основанный на Camera2 API. Этот тип расширителя был добавлен в 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: проверьте доступность расширений
Рис. 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()
выполняет очистку.
Поддержка предварительного просмотра, фотосъемки и анализа изображений.
Вы должны применить расширение как для предварительного просмотра, так и для фиксирования вариантов использования. Однако, если задержка слишком велика для плавного отображения предварительного просмотра, вы можете применить эффект только для неподвижного захвата.
Для типа Basic Extender, независимо от включения эффекта для предварительного просмотра, необходимо реализовать как ImageCaptureExtenderImpl
, так и PreviewExtenderImpl
для данного расширения. Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888
stream for configuring CameraCaptureSession
. This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888
streams.
For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession()
call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
. This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession()
.
Support video capture
The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec
or MediaRecorder
surfaces for recording the video. However, it's possible for apps to record the preview output.
Supporting MediaCodec
and MediaRecorder
surfaces is under investigation.
Extensions interface version history
The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.
Version | Added features |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
Reference implementation
For a reference OEM vendor library implementation, see camera-testlib-extensions
. Note that this implementation performs passthroughs without actually implementing the effects.
Set up the vendor library on a device
The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library>
tag declares that the androidx.camera.extensions.impl
library, which is defined in the AndroidManifest.xml
file of the camera-extensions
library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library>
loads the same androidx.camera.extensions.impl
library at runtime.
This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.
To set up the OEM library on a device, do the following:
- Add a permission file, which is required by the
<uses-library>
tag, using the following format:/etc/permissions/ ANY_FILENAME .xml
. For example,/etc/permissions/camera_extensions.xml
. The files in this directory provide a mapping of the library named in<uses-library>
to the actual file path on the device. Use the example below to add the required information to the file.
-
name
must beandroidx.camera.extensions.impl
as that's the library that CameraX searches for. -
file
is the absolute path of the file that contains the extensions implementation (for example,/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>
-
In Android 12 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled
property set to true
, which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Validation
To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/
, which runs through various vendor extensions.
After you complete your implementation, use the Camera Extensions Validation Tool to run automated and manual tests to verify that the vendor library is implemented correctly.
Frequently asked questions (FAQs)
Are there any restrictions on API levels?
Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession()
uses the SessionConfiguration.setSessionParameters()
call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .