תחילת השימוש בממשקי Media Enhancement API

‫Media Enhancement API הוא כלי רב עוצמה שמבוסס על שיפור המהירות באמצעות GPU במכשיר, כדי לשפר תמונות באיכות גבוהה עם זמן אחזור נמוך. התכונות האלה כוללות מיפוי טונים אוטומטי, ביטול טשטוש, ביטול רעשים והגדלת רזולוציה.

לפני שמפעילים את ה-API, צריך להגדיר את התלות של הפרויקט ולהצהיר על דרישות להאצת חומרה במניפסט. הסיבה העיקרית לשגיאות זמן ריצה GLOBAL_INIT_FAILED היא דילוג על ההגדרות האלה.

יחסי תלות של Gradle

מוסיפים את יחסי התלות הבאים לקובץ app/build.gradle.kts. כדי לאפשר ביצוע אסינכרוני ולא חוסם, צריך לכלול שגרות משנה של Kotlin ו-Jetpack Media3 לטיפול במשטחי חומרה.

dependencies {
    // Google Play services Media Enhancement Library (Beta)
    implementation("com.google.android.gms:play-services-media-effect-enhancement:16.0.0-beta04")
}

פרטים על החבילה play-services-media-effect-enhancement זמינים במאגר Maven של Google.

מומלץ גם להשתמש ב-Kotlin coroutines כדי לנהל את הפעלות השיפור באופן אסינכרוני.

// Kotlin coroutines for asynchronous API handling
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3")

דרישות לגבי מניפסט Android

מוסיפים את הרכיבים הבאים לתג <application> בקובץ AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <!-- 1. Google Play services version for runtime compatibility checks -->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <!-- 2. Declare OpenCL compute libraries for NPU/GPU neural acceleration -->
        <uses-native-library android:name="libOpenCL.so" android:required="false" />
        <uses-native-library android:name="libOpenCL-car.so" android:required="false" />
        <uses-native-library android:name="libOpenCL-pixel.so" android:required="false" />
        <!-- 3. Declare OpenGL ES for high-performance graphics rendering -->
        <uses-native-library android:name="libGLESv2.so" android:required="false" />
        <uses-native-library android:name="libGLESv3.so" android:required="false" />
    </application>
</manifest>

‫OpenCL מספקת את ספריות המחשוב המקוריות שנדרשות להפעלת האצת רשתות עצביות של NPU ו-GPU למשימות של שיפור המדיה. הצהרה על הספריות האלה במניפסט היא תנאי מוקדם לשימוש ב-API כדי למנף את האצת החומרה, שהיא חיונית לביצוע שיפורים באיכות גבוהה עם השהיה נמוכה. מידע נוסף על OpenCL זמין במאמר הטמעות של OpenCL.

‫OpenGL ES מספק את ספריות הגרפיקה המקוריות שנדרשות לעיבוד של פלט שיפור המדיה בביצועים גבוהים. הצהרה על הספריות האלה במניפסט חיונית כדי להבטיח שצינור עיבוד הנתונים יוכל להציג ביעילות מדיה שעברה עיבוד במשטחים עם האצת חומרה. מידע על OpenGL זמין במאמרי העזרה של ה-API של OpenGL.

צינור העיבוד (rendering) של Android חייב להיות מואץ באמצעות חומרה כדי למנוע צווארי בקבוק. ההגדרה הזו מופעלת כברירת מחדל באפליקציות שמטרגטות API ברמה 14 ומעלה, אבל צריך להגדיר אותה באופן מפורש בתגי android:hardwareAccelerated="true"<activity>.

תאימות מכשירים והגדרת מודולים

Google Play Services מספקים מודלים של למידת מכונה באופן דינמי כדי לחסוך במקום האחסון של קובץ ה-APK הראשוני. לפני שמבצעים שיפורים, האפליקציה צריכה להשתמש ב-EnhancementClient כדי לאמת את תמיכת החומרה ולוודא שהמשקלים של המודל הדרוש הורדו ונשמרו במטמון באופן מקומי. זהו תהליך חד-פעמי לכל מכשיר.

באמצעות suspendCancellableCoroutine, אפשר לעטוף את הקריאות החוזרות (callback) של הלקוח שמבוסס על משימות בפונקציות השהיה רגילות של Kotlin, כדי להשיג ביצוע נקי ורציף:

// Verifies if host hardware supports NPU/GPU acceleration
suspend fun EnhancementClient.isDeviceSupportedAsync(): Boolean = suspendCancellableCoroutine { continuation ->
    this.isDeviceSupported()
        .addOnSuccessListener { result -> continuation.resume(result) }
        .addOnFailureListener { exception -> continuation.resumeWithException(exception) }
}
// Verifies the presence of required neural network models
suspend fun EnhancementClient.isModuleInstalledAsync(): Boolean = suspendCancellableCoroutine { continuation ->
    this.isModuleInstalled()
        .addOnSuccessListener { result -> continuation.resume(result) }
        .addOnFailureListener { exception -> continuation.resumeWithException(exception) }
}