Разберитесь в жизненном цикле улучшения мультимедиа в режиме Surface.

API улучшения качества мультимедиа предоставляет решение на основе искусственного интеллекта с низкой задержкой и сохранением конфиденциальности, работающее непосредственно на устройстве и использующее аппаратное ускорение для улучшения качества мультимедиа без увеличения размера APK-файла. Для получения дополнительной информации см. раздел «Ознакомление с возможностями улучшения качества мультимедиа» .

На следующей архитектурной диаграмме показан жизненный цикл выполнения API улучшения мультимедиа в асинхронном режиме. Этот режим напрямую связывает аппаратные буферы, устраняя узкое место в производительности, связанное с копированием несжатых кадров между буферами памяти ЦП и ГП.

Диаграмма, иллюстрирующая 7-этапный асинхронный жизненный цикл взаимодействия между поверхностями API улучшения мультимедиа.
Рисунок 1. Жизненный цикл выполнения асинхронного режима поверхности и семь практических шагов конвейера усовершенствования.

Процесс усовершенствования реализуется в несколько этапов:

Этап 1. Настройка сессии улучшения.

1. Предоставьте входную поверхность : Ваше приложение предоставляет фреймворку расширений дескриптор входной поверхности для доступа к кадрам для обработки.

2. Настройка выходной поверхности : Ваше приложение создает и привязывает целевые объекты рендеринга (например, SurfaceView или TextureView ) непосредственно к фреймворку.

Этап 2. Создание входного кадра.

3. Подготовка базового медиафайла : Ваше приложение получает базовый несжатый медиафайл. Например, путем чтения файла с локального диска.

4. Внедрение данных кадра : Ваше приложение записывает необработанные данные изображения непосредственно в связанный конвейер обработки входных данных.

Этап 3. Обработка и совершенствование.

5. Выполнение обработки с помощью ИИ : фреймворк обрабатывает кадр на графическом или нейронном процессоре устройства, применяя методы машинного обучения, такие как тональное отображение, устранение размытия или масштабирование.

6. Выдача улучшенного кадра : движок выводит улучшенный кадр с полным разрешением непосредственно на связанную выходную поверхность.

Этап 4. Отображение или сохранение результата.

7. Завершение вывода : Ваше приложение получает обработанный аппаратный буфер потока для отображения в пользовательском интерфейсе или сохранения обратно в хранилище.

EnhancementSession — это ресурсоёмкий контекстный объект, поддерживающий постоянный конвейер обработки памяти графического или нейронного процессора. Он выделяет выделенную видеопамять (VRAM) и собственные системные дескрипторы. Для предотвращения серьёзных утечек памяти и потенциальных сбоев OutOfMemoryError следует придерживаться следующих принципов жизненного цикла:

  • Ленивое создание экземпляра : не создавайте сессию до тех пор, пока пользователь не инициирует действие по улучшению.
  • Стратегическое повторное использование : Поддерживайте и повторно используйте один экземпляр сессии при обработке потоков или кадров с идентичными конфигурациями (размерами и переключаемыми параметрами).
  • Завершение сессии : Вызывайте session.release() немедленно после завершения визуальных задач, чтобы освободить общие аппаратные ресурсы.

Инициализировать механизм улучшений

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

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

class MediaSetupViewModel(application: Application) : AndroidViewModel(application) {
    private val enhancementClient = Enhancement.getClient(application)
    fun initializeEnhancementEngine() {
        viewModelScope.launch {
            try {
                // 1. Verify hardware capability
                val isSupported = enhancementClient.isDeviceSupportedAsync()
                if (!isSupported) {
                    notifyUiDeviceIncompatible()
                    return@launch
                }
                // 2. Verify and download the Google Play services ML modules
                val isInstalled = enhancementClient.isModuleInstalledAsync()
                if (!isInstalled) {
                    notifyUiDownloadingModels()
                    enhancementClient.installModule().await() 
                }
                notifyUiEngineReady()
            } catch (e: Exception) {
                // Handle potential errors during session creation or image
                // processing.
                handleInitializationError(e)
            }
        }
    }
}

Реализация: Поверхностный режим (поверхность внутрь, поверхность наружу)

Режим выполнения Surface ( EnhancementMode.SURFACE ) позволяет избежать накладных расходов на перемещение кадров между буферами памяти ЦП и ГП. Вместо этого библиотека улучшений напрямую сопоставляет необработанные аппаратные буферы, считывая кадры с входной поверхности Surface, обрабатывая их нативно и передавая непосредственно на выходную поверхность Surface.

Однокадровые снимки поверхности

Этот метод используется для эффективного применения эффектов к одному кадру изображения, декодированному аппаратным способом.

// Provisions input Surface (for example, ImageReader) and output Surface (for
// example, SurfaceView)
val inputSurface: Surface = imageReader.surface
val outputSurface: Surface = surfaceView.holder.surface
// 1. Configure parameters for SURFACE mode
val surfaceOptions = EnhancementOptions(
    imageReader.width,
    imageReader.height,
    EnhancementMode.SURFACE,
    enableTonemap = true,
    enableDeblurDenoise = true,
    enableFaceDetection = false
).also {
    // 2. Bind hardware surfaces
    it.setInputSurface(inputSurface)
    it.setOutputSurface(outputSurface)
}

// 3. Create the session to process the hardware frame
val singleFrameSession = enhancementClient.createSessionAsync(surfaceOptions, executor)
// The API processes the single frame. Upon completion, release the session.
singleFrameSession.release()