Interfejs Media Enhancement API udostępnia rozwiązanie AI działające na urządzeniu, które zapewnia niskie opóźnienie i ochronę prywatności. Wykorzystuje ono przyspieszenie sprzętowe, aby poprawiać jakość multimediów bez zwiększania rozmiaru pliku APK. Więcej informacji znajdziesz w artykule Omówienie funkcji poprawiania jakości multimediów.
Poniższy schemat architektury przedstawia cykl życia asynchronicznego trybu powierzchniowego 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 CPU i GPU.
Potok ulepszania jest implementowany w tych krokach:
Etap 1. Konfigurowanie sesji ulepszania
1. Podaj powierzchnię wejściową: Twoja aplikacja udostępnia platformie ulepszania uchwyt powierzchni wejściowej, aby uzyskać dostęp do klatek do przetworzenia.
2. Ustaw powierzchnię wyjściową: Twoja aplikacja udostępnia i wiąże cele renderowania
(np. SurfaceView lub TextureView) bezpośrednio z platformą.
Etap 2. Tworzenie klatki wejściowej
3. Przygotuj podstawowe multimedia: Twoja aplikacja pobiera podstawowe nieskompresowane multimedia. Może to zrobić np. przez odczytanie pliku z dysku lokalnego.
4. Wstrzykiwanie danych klatki: Twoja aplikacja zapisuje nieprzetworzone dane obrazu bezpośrednio w powiązanym potoku powierzchni wejściowej.
Etap 3. Przetwarzanie i ulepszanie
5. Wykonaj przetwarzanie AI: platforma przetwarza klatkę na GPU lub NPU urządzenia, stosując ulepszenia uczenia maszynowego, takie jak mapowanie tonalne, usuwanie rozmycia lub skalowanie.
6. Dostarcz ulepszoną klatkę: silnik przesyła ulepszoną klatkę w pełnej rozdzielczości bezpośrednio do powiązanej powierzchni wyjściowej.
Etap 4. Wyświetlanie lub zapisywanie wyniku
7. Finalizowanie danych wyjściowych: Twoja aplikacja otrzymuje przetworzony bufor strumienia sprzętowego aby renderować go w interfejsie lub zapisać w pamięci.
Obiekt EnhancementSession to złożony obiekt kontekstu, który utrzymuje trwały potok pamięci GPU lub NPU. Przydziela on dedykowaną pamięć RAM wideo (VRAM) i natywne uchwyty systemowe. Aby zapobiec poważnym wyciekom pamięci i potencjalnym awariom spowodowanym błędem OutOfMemoryError, przestrzegaj tych zasad cyklu życia:
- Opóźnione tworzenie instancji: nie twórz sesji, dopóki użytkownik nie zainicjuje działania ulepszającego.
- 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).
- Szybkie zamykanie: natychmiast po zakończeniu zadań wizualnych
wywołaj
session.release(), aby zwolnić współdzielone zasoby sprzętowe.
Inicjowanie silnika ulepszania
Ta metoda koordynuje dwuetapowe sprawdzanie. Sprawdza, czy sprzęt urządzenia obsługuje przyspieszenie, a następnie czy są dostępne wymagane moduły uczenia maszynowego.
Uruchomienie tej metody jako kroku wstępnego zapobiega błędom inicjowania w czasie działania, ponieważ sprawdza możliwości przed próbą przetworzenia multimediów przez aplikację.
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)
}
}
}
}
Implementacja: tryb powierzchniowy (powierzchnia wejściowa, powierzchnia wyjściowa)
Tryb wykonywania powierzchniowego (EnhancementMode.SURFACE) pozwala uniknąć obciążenia związanego z przenoszeniem klatek między buforami pamięci CPU i GPU. Zamiast tego biblioteka ulepszania bezpośrednio mapuje nieprzetworzone bufory sprzętowe, odczytując klatki z powierzchni wejściowej, przetwarzając je natywnie i przesyłając bezpośrednio do powierzchni wyjściowej.
Migawki powierzchniowe pojedynczych klatek
Ta metoda służy do efektywnego stosowania efektów do pojedynczej klatki obrazu dekodowanego 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()