Poznaj cykl życia ulepszania multimediów w trybie Surface

Interfejs Media Enhancement API to działające na urządzeniu rozwiązanie oparte na sztucznej inteligencji, które zapewnia niskie opóźnienia i chroniące prywatność. Wykorzystuje akcelerację sprzętową, aby poprawiać jakość multimediów bez zwiększania rozmiaru pakietu APK. Więcej informacji znajdziesz w artykule Omówienie funkcji ulepszania multimediów.

Poniższy schemat architektury przedstawia cykl życia asynchronicznego trybu działania interfejsu Media Enhancement API. Ten tryb bezpośrednio łączy bufory sprzętowe, aby wyeliminować wąskie gardło wydajności związane z kopiowaniem nieskompresowanych klatek między buforami pamięci procesora i GPU.

Diagram ilustrujący 7-etapowy asynchroniczny cykl życia interfejsu Media Enhancement API typu surface-to-surface.
Rysunek 1. Cykl życia wykonywania trybu asynchronicznego i 7 praktycznych kroków potoku ulepszeń.

Potok ulepszeń jest wdrażany w tych krokach:

Etap 1. Konfigurowanie sesji ulepszania

1. Udostępnij powierzchnię wejściową: aplikacja udostępnia platformie ulepszania uchwyt powierzchni wejściowej, aby uzyskać dostęp do klatek do przetworzenia.

2. Ustaw powierzchnię wyjściową: aplikacja udostępnia i wiąże cele renderowania (np. SurfaceView lub TextureView) bezpośrednio z platformą.

Etap 2. Utwórz klatkę wejściową.

3. Przygotuj podstawowe multimedia: aplikacja pobiera podstawowe nieskompresowane multimedia. Na przykład przez odczytanie pliku z dysku lokalnego.

4. Wstrzykiwanie danych klatki: aplikacja zapisuje surowe dane obrazu bezpośrednio w powiązanym potoku powierzchni wejściowej.

Etap 3. Przetwarzanie i ulepszanie

5. Wykonanie przetwarzania AI: framework przetwarza klatkę na GPU lub NPU urządzenia, stosując ulepszenia wynikające z uczenia maszynowego, takie jak mapowanie tonalne, usuwanie rozmycia czy skalowanie w górę.

6. Przekazywanie ulepszonej klatki: silnik przekazuje ulepszoną klatkę w pełnej rozdzielczości bezpośrednio do powiązanej powierzchni wyjściowej.

Etap 4. Wyświetlanie lub zapisywanie wyniku

7. Końcowe dane wyjściowe: aplikacja otrzymuje przetworzony bufor strumienia sprzętowego, aby renderować go w interfejsie lub zapisywać z powrotem w pamięci.

EnhancementSession to obiekt kontekstu o dużej wadze, który utrzymuje trwały potok pamięci GPU lub NPU. Przydziela dedykowaną pamięć RAM wideo (VRAM) i natywne uchwyty systemowe. Aby zapobiec poważnym wyciekom pamięci i potencjalnym OutOfMemoryErrorawariom, przestrzegaj tych zasad cyklu życia:

  • Lenistwo w tworzeniu instancji: nie twórz sesji, dopóki użytkownik nie zainicjuje działania związanego z ulepszaniem.
  • Strategiczne ponowne użycie: utrzymuj i ponownie używaj pojedynczej instancji sesji podczas przetwarzania strumieni lub klatek o identycznych konfiguracjach (wymiarach i włączonych opcjach).
  • Zakończenie promptu: wywołuj session.release() natychmiast po zakończeniu zadań wizualnych, aby zwolnić współdzielone zasoby sprzętowe.

Inicjowanie silnika ulepszania

Ta metoda przeprowadza dwuetapową weryfikację. Sprawdza, czy sprzęt urządzenia obsługuje akcelerację, a następnie upewnia się, że są obecne wymagane moduły uczenia maszynowego.

Uruchomienie tego kroku jako warunku wstępnego zapobiega błędom inicjowania w czasie działania, ponieważ sprawdza możliwości przed podjęciem przez aplikację próby przetworzenia multimediów.

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

Wdrożenie: tryb powierzchniowy (powierzchnia wewnątrz, powierzchnia na zewnątrz)

Tryb wykonywania Surface (EnhancementMode.SURFACE) pozwala uniknąć obniżenia wydajności związanego z przenoszeniem ramek między buforami pamięci procesora i GPU. Zamiast tego biblioteka ulepszeń mapuje bezpośrednio surowe bufory sprzętowe, odczytując klatki z powierzchni wejściowej, przetwarzając je natywnie i przesyłając bezpośrednio na powierzchnię wyjściową.

Zrzuty powierzchni w jednej klatce

Ta metoda służy do efektywnego stosowania efektów do pojedynczej ramki obrazu dekodowanej sprzętowo.

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