Media Enhancement API הוא פתרון AI במכשיר ששומר על הפרטיות, עם זמן טעינה נמוך, שממנף האצת חומרה כדי לספק שיפורים באיכות המדיה ללא ניפוח של קובץ ה-APK. מידע נוסף זמין במאמר בנושא הסבר על יכולות שיפור המדיה.
בתרשים הארכיטקטורה הבא מוצג מחזור החיים של ביצוע Media Enhancement API במצב אסינכרוני של Surface. במצב הזה, מאגרי חומרה מקושרים ישירות כדי למנוע את צוואר הבקבוק בביצועים שנוצר מהעתקה של פריימים לא דחוסים הלוך ושוב בין מאגרי הזיכרון של המעבד ושל ה-GPU.
תהליך השיפור מיושם באמצעות השלבים הבאים:
שלב 1. הגדרת סשן שיפור
1. מספקים משטח קלט: האפליקציה מספקת למסגרת השיפורים נקודת אחיזה למשטח קלט כדי לגשת למסגרות לצורך עיבוד.
2. הגדרת משטח הפלט: האפליקציה שלכם מקצה ומקשרת יעדי עיבוד (למשל SurfaceView או TextureView) ישירות למסגרת.
שלב 2. יצירת פריים קלט
3. הכנת מדיה בסיסית: האפליקציה מאחזרת את המדיה הבסיסית הלא דחוסה. לדוגמה, על ידי קריאת קובץ מדיסק מקומי.
4. החדרת נתוני מסגרת: האפליקציה כותבת את מטען התמונה הגולמי ישירות לצינור של משטח הקלט המקביל.
שלב 3. עיבוד ושיפור
5. ביצוע עיבוד באמצעות AI: המסגרת מעבדת את הפריים ב-GPU או ב-NPU של המכשיר, ומיישמת שיפורים של למידת מכונה כמו מיפוי טונים, הסרת טשטוש או הגדלת רזולוציה.
6. Deliver enhanced frame (הצגת פריים משופר): המנוע מוציא את הפריים המשופר ברזולוציה מלאה ישירות למשטח הפלט המוגדר.
שלב 4. הצגה או שמירה של התוצאה
7. סיום הפלט: האפליקציה מקבלת את מאגר הנתונים הזמני של הזרם המעובד מהחומרה כדי להציג אותו בממשק המשתמש או לשמור אותו בחזרה באחסון.
EnhancementSession הוא אובייקט הקשר כבד ששומר על צינור זיכרון מתמשך של GPU או NPU. הוא מקצה זיכרון RAM (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) מאפשר להימנע מהתקורה של הביצועים שנובעת מהעברת פריימים בין מאגרי הזיכרון של המעבד ושל ה-GPU. במקום זאת, ספריית השיפורים ממפה ישירות את מאגרי הנתונים הגולמיים של החומרה, קוראת את הפריימים מ-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()