Примечание: Эта страница относится к пакету Camera2 . Если вашему приложению не требуются специфические низкоуровневые функции Camera2, мы рекомендуем использовать CameraX . И CameraX, и Camera2 поддерживают Android 5.0 (уровень API 21) и выше.
API Camera2 поддерживают захват видео с расширенным динамическим диапазоном (HDR), что позволяет просматривать и записывать HDR-видеоконтент с помощью камеры. По сравнению со стандартным динамическим диапазоном (SDR), HDR предлагает более широкий диапазон цветов и увеличивает динамический диапазон компонента яркости (с текущих 100 кд/м² до тысяч кд/м²). Это приводит к качеству видео, более точно соответствующему реальной жизни, с более насыщенными цветами, более яркими бликами и более темными тенями.
Посмотрите, как HDR-видео запечатлевает закат в более ярких и детализированных кадрах.


Требования к устройству
Не все устройства Android поддерживают запись HDR-видео. Прежде чем записывать HDR-видео в своем приложении, убедитесь, что ваше устройство соответствует следующим требованиям:
- Предназначен для Android 13 (уровень API 33).
- Имеет датчик камеры с поддержкой 10-битной или более высокой четкости. Для получения дополнительной информации о поддержке HDR см. раздел «Проверка поддержки HDR» .
Поскольку не все устройства соответствуют необходимым требованиям, вы можете добавить отдельный путь выполнения кода при настройке захвата HDR-видео в вашем приложении. Это позволит вашему приложению переключаться на SDR на несовместимых устройствах. Также рассмотрите возможность добавления опции пользовательского интерфейса для SDR. Пользователь сможет переключаться между SDR и HDR в зависимости от своих потребностей в видеозаписи.
архитектура захвата HDR
На следующей диаграмме показаны основные компоненты архитектуры захвата HDR-изображений.

Когда камера захватывает кадр в режиме HDR, платформа Camera2 выделяет буфер для хранения обработанного выходного сигнала датчика камеры. Она также добавляет соответствующие метаданные HDR, если это требуется профилем HDR. Затем платформа Camera2 ставит заполненный буфер в очередь для выходной поверхности, указанной в запросе CaptureRequest , например, дисплея или видеокодера, как показано на диаграмме.
Проверьте наличие поддержки HDR.
Перед записью HDR-видео в приложении убедитесь, что устройство поддерживает желаемый HDR-профиль.
Используйте метод ` getCameraCharacteristics() ` CameraManager , чтобы получить экземпляр CameraCharacteristics , из которого можно запросить информацию о возможностях HDR вашего устройства.
Следующие шаги проверяют, поддерживает ли устройство HLG10. HLG10 — это базовый стандарт HDR, который производители устройств обязаны поддерживать на камерах с 10-битным выводом.
Для начала проверьте, поддерживает ли устройство 10-битные профили (разрядность для HLG10):
Котлин
private fun isTenBitProfileSupported(cameraId: String): Boolean { val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableCapabilities = cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) for (capability in availableCapabilities!!) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { return true } } return false }
Далее проверьте, поддерживает ли устройство профиль HLG10 (или другой поддерживаемый профиль ):
Котлин
@RequiresApi(api = 33) private fun isHLGSupported(cameraId: String): Boolean { if (isTenBitProfileSupported(cameraId)) { Val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableProfiles = cameraCharacteristics .get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES)!! .getSupportedProfiles() // Checks for the desired profile, in this case HLG10 return availableProfiles.contains(DynamicRangeProfiles.HLG10) } return false; }
Если устройство поддерживает HDR, isHLGSupported() всегда возвращает true . Для получения дополнительной информации см. справочную документацию CameraCharacteristics .
Настройка захвата HDR
Убедившись, что ваше устройство поддерживает HDR, настройте приложение для захвата необработанного видеопотока HDR с камеры. Используйте setDynamicRangeProfile() , чтобы указать OutputConfiguration поддерживаемый устройством профиль HDR, который затем передается в CameraCaptureSession при создании. См. список поддерживаемых профилей HDR.
В приведенном ниже примере кода функция setupSessionDynamicRangeProfile() сначала проверяет, работает ли устройство под управлением Android 13. Затем она настраивает CameraCaptureSession с поддерживаемым устройством профилем HDR в качестве OutputConfiguration :
Котлин
/** * Creates a [CameraCaptureSession] with a dynamic range profile. */ private fun setupSessionWithDynamicRangeProfile( dynamicRange: Long, device: CameraDevice, targets: List, handler: Handler? = null, stateCallback: CameraCaptureSession.StateCallback ): Boolean { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { val outputConfigs = mutableListOf () for (target in targets) { val outputConfig = OutputConfiguration(target) //sets the dynamic range profile, for example DynamicRangeProfiles.HLG10 outputConfig.setDynamicRangeProfile(dynamicRange) outputConfigs.add(outputConfig) } device.createCaptureSessionByOutputConfigurations( outputConfigs, stateCallback, handler ) return true } else { device.createCaptureSession(targets, stateCallback, handler) return false } }
Когда ваше приложение камеры инициализирует камеру, оно отправляет повторяющийся CaptureRequest для предварительного просмотра записи:
Котлин
session.setRepeatingRequest(previewRequest, null, cameraHandler)
А также, чтобы начать видеозапись:
Котлин
// Start recording repeating requests, which stops the ongoing preview // repeating requests without having to explicitly call // `session.stopRepeating` session.setRepeatingRequest(recordRequest, object : CameraCaptureSession.CaptureCallback() { override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) { if (currentlyRecording) { encoder.frameAvailable() } } }, cameraHandler)
Кодирование видеопотока с HDR-камеры
Для кодирования HDR-потока с камеры и записи файла на диск используйте MediaCodec .
Сначала получите OutputSurface , который соответствует буферу, хранящему необработанные видеоданные. Для MediaCodec используйте createInputSurface() .
Для инициализации MediaCodec приложение должно создать объект MediaFormat с указанным профилем кодека, цветовым пространством, диапазоном цветов и функцией передачи:
Котлин
val mimeType = when { dynamicRange == DynamicRangeProfiles.STANDARD -> MediaFormat.MIMETYPE_VIDEO_AVC dynamicRange < DynamicRangeProfiles.PUBLIC_MAX -> MediaFormat.MIMETYPE_VIDEO_HEVC else -> throw IllegalArgumentException("Unknown dynamic range format") } val codecProfile = when { dynamicRange == DynamicRangeProfiles.HLG10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 dynamicRange == DynamicRangeProfiles.HDR10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 dynamicRange == DynamicRangeProfiles.HDR10_PLUS -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus else -> -1 } // Failing to correctly set color transfer causes quality issues // for example, washout and color clipping val transferFunction = when (codecProfile) { MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 -> MediaFormat.COLOR_TRANSFER_HLG MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 -> MediaFormat.COLOR_TRANSFER_ST2084 MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus -> MediaFormat.COLOR_TRANSFER_ST2084 else -> MediaFormat.COLOR_TRANSFER_SDR_VIDEO } val format = MediaFormat.createVideoFormat(mimeType, width, height) // Set some properties. Failing to specify some of these can cause the MediaCodec // configure() call to throw an exception. format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface) format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate) format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate) format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL) if (codecProfile != -1) { format.setInteger(MediaFormat.KEY_PROFILE, codecProfile) format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT2020) format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, transferFunction) format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing, true) } mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
Более подробную информацию о реализации см. в EncoderWrapper.kt демонстрационного приложения Camera2Video.
Форматы HDR
Начиная с Android 13, устройства с камерой, поддерживающие 10-битный вывод изображения, должны поддерживать HLG10 для захвата и воспроизведения HDR-контента. Кроме того, производители устройств могут включать любой формат HDR по своему выбору, используя архитектуру захвата HDR .
В таблице ниже приведено краткое описание доступных форматов HDR и их возможностей для захвата HDR-видео.
| Формат | Передаточная функция (ПФ) | Метаданные | Кодек | Глубина бита |
|---|---|---|---|---|
| HLG10 | HLG | Нет | HEVC | 10-битный |
| HDR10 | ПК | Статический | HEVC | 10-битный |
| HDR10+ | ПК | Динамический | HEVC | 10-битный |
| Dolby Vision 8.4 | HLG | Динамический | HEVC | 10-битный |