Производители устройств могут предоставлять сторонним разработчикам такие расширения, как боке, ночной режим и 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. Реализация ночного расширения
Проверка версии:
Camera2/X вызывает
ExtensionVersionImpl.checkApiVersion()
, чтобы убедиться, что версияextensions-interface
реализованная OEM-производителем, совместима с поддерживаемыми версиями Camera2/X.Инициализация библиотеки поставщика:
InitializerImpl
имеет методinit()
, который инициализирует библиотеку поставщика. Camera2/X завершает инициализацию перед доступом к классам Extender.Создание экземпляров классов расширителей:
Создает экземпляры классов 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
-
Проверьте доступность расширения:
Прежде чем включить расширение,
isExtensionAvailable()
проверяет, доступно ли расширение для указанного идентификатора камеры через экземпляр Extender.Инициализируйте повторитель, используя информацию о камере:
Camera2/X вызывает
init()
экземпляра Extender и передает ему идентификатор камеры иCameraCharacteristics
.Информация о запросе:
Вызывает класс 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. Однако при проверке версии используются только основная и дополнительная версии.
Чтобы проверить версию, 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 вызывает |
Крючки в конвейере камеры |
|
|
Подходит для | Расширения реализованы в 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, вы должны правильно реализовать библиотеку поставщика для поддержки этих потоков, которые мы опишем более подробно в следующем разделе.
Расширения камеры2 | Расширения CameraX | |
---|---|---|
Доступность расширения запроса | CameraExtensionCharacteristics . getSupportedExtensions | ExtensionsManager. isExtensionAvailable |
Запросить информацию | CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys | ExtensionsManager. getEstimatedCaptureLatencyRange CameraX обрабатывает остальную информацию в библиотеке. |
Предварительный просмотр и съемка фотографий с включенным расширением | CameraDevice. createExtensionSession | val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector связываниеToLifecycle(lifecycleOwner, cameraSelector, предварительный просмотр,...) |
Базовый расширитель
Интерфейс Basic Extender обеспечивает перехваты в нескольких местах конвейера камеры. Каждый тип расширения имеет соответствующие классы расширителей, которые необходимо реализовать OEM-производителям.
В следующей таблице перечислены классы расширителей, которые OEM-производители должны реализовать для каждого расширения:
Классы расширения для реализации | |
---|---|
Ночь | NightPreviewExtenderImpl.java |
HDR | HdrPreviewExtenderImpl.java |
Авто | AutoPreviewExtenderImpl.java |
Боке | BokehPreviewExtenderImpl.java |
Ретушь лица | BeautyPreviewExtenderImpl.java |
В следующем примере мы используем PreviewExtenderImpl
и ImageCaptureExtenderImpl
в качестве заполнителей. Замените их именами реальных файлов, которые вы реализуете.
Базовый расширитель имеет следующие возможности:
- Вставьте параметры сеанса при настройке
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()
для этих классов Extender, прежде чем запрашивать дополнительную информацию.
Последовательность действий приложения 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 отправляет три запроса захвата с соответствующими параметрами захвата, используя 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. Этот тип расширителя был добавлен в 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
для данного расширения. Часто в приложении также используется поток 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-интерцензии 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. camera-extensions
<uses-library>
androidx.camera.extensions.impl
AndroidManifest.xml
быть загружена. В Camera2 фреймворк загружает службу расширений, которая также заявляет, что <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 .