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