Comprendre le cycle de vie de l'amélioration multimédia en mode Surface

L'API Media Enhancement fournit une solution d'IA sur l'appareil à faible latence et protégeant la confidentialité qui exploite l'accélération matérielle pour offrir des améliorations multimédias de haute qualité sans gonflement de l'APK. Pour en savoir plus, consultez Comprendre les fonctionnalités d'amélioration multimédia.

Le schéma d'architecture suivant illustre le cycle de vie de l'exécution en mode de surface asynchrone de l'API Media Enhancement. Ce mode associe directement les tampons matériels pour éliminer le goulot d'étranglement des performances lié à la copie des frames non compressées entre les tampons de mémoire du processeur et du GPU.

Diagramme illustrant le cycle de vie asynchrone de bout en bout en sept étapes de l'API Media Enhancement.
Image 1. Cycle de vie de l'exécution en mode de surface asynchrone et sept étapes concrètes du pipeline d'amélioration

Le pipeline d'amélioration est implémenté en procédant comme suit :

Étape 1. Configurer la session d'amélioration

1. Fournir une surface d'entrée : votre application fournit au framework d'amélioration un descripteur de surface d'entrée pour accéder aux frames à traiter.

2. Définir la surface de sortie : votre application provisionne et lie les cibles de rendu (telles qu'un SurfaceView ou un TextureView) directement au framework.

Étape 2. Produire une frame d'entrée

3. Préparer le média de base : votre application récupère le média de base non compressé. Par exemple, en lisant un fichier à partir d'un disque local.

4. Injecter des données de frame : votre application écrit la charge utile de l'image brute directement dans le pipeline de surface d'entrée lié.

Étape 3. Traiter et améliorer

5. Exécuter le traitement par IA : le framework traite la frame sur le GPU ou le NPU de l'appareil, en appliquant des améliorations de machine learning telles que le mappage de tonalités, la suppression du flou ou la mise à l'échelle.

6. Fournir une frame améliorée : le moteur génère la frame améliorée en pleine résolution frame directement sur la surface de sortie liée.

Étape 4. Afficher ou enregistrer le résultat

7. Finaliser la sortie : votre application reçoit le tampon de flux matériel traité pour l'afficher dans l'interface utilisateur ou l'enregistrer dans le stockage.

EnhancementSession est un objet de contexte lourd qui gère un pipeline de mémoire GPU ou NPU persistant. Il alloue de la RAM vidéo (VRAM) dédiée et des descripteurs de système natifs. Pour éviter les fuites de mémoire graves et les plantages potentiels OutOfMemoryError, respectez les principes de cycle de vie suivants :

  • Instanciation différée : ne créez pas de session tant que l'utilisateur n'a pas lancé d'action d'amélioration.
  • Réutilisation stratégique : conservez et réutilisez une seule instance de session lorsque vous traitez des flux ou des frames avec des configurations identiques (dimensions et options activées/désactivées).
  • Démontage rapide : appelez session.release() immédiatement lorsque les tâches visuelles se terminent pour libérer les ressources matérielles partagées.

Initialiser le moteur d'amélioration

Cette méthode orchestre une vérification en deux étapes. Elle vérifie si le matériel de l'appareil est compatible avec l'accélération, puis s'assure que les modules de machine learning requis sont présents.

L'exécution de cette étape préalable empêche les échecs d'initialisation au moment de l'exécution en validant les capacités avant que votre application ne tente de traiter des contenus multimédias.

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)
            }
        }
    }
}

Implémentation : mode de surface (surface en entrée, surface en sortie)

Le mode d'exécution de surface (EnhancementMode.SURFACE) évite la surcharge de performances liée au déplacement des frames entre les tampons de mémoire du processeur et du GPU. Au lieu de cela, la bibliothèque d'amélioration mappe directement les tampons matériels bruts, en lisant les frames à partir d'une surface d'entrée, en les traitant de manière native et en les transmettant directement à une surface de sortie.

Instantanés de surface à une seule frame

Cette méthode permet d'appliquer efficacement des effets à une seule frame d'image décodée par le matériel.

// 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()