תכונת הקידוד מחדש של מדיה תואמת, שהושקה ב-Android 12, מאפשרת למכשירים להשתמש בפורמטים מודרניים יותר של מדיה שחוסכים מקום באחסון לצילום וידאו, כמו HEVC, תוך שמירה על תאימות לאפליקציות. התכונה הזו מאפשרת ליצרני מכשירים להשתמש ב-HEVC במקום ב-AVC כברירת מחדל, כדי לשפר את איכות הווידאו תוך צמצום הדרישות לגבי אחסון ורוחב פס. במכשירים שבהם מופעלת המרת קודקים של מדיה תואמת, מערכת Android יכולה להמיר אוטומטית סרטונים (באורך של עד דקה) שצולמו בפורמטים כמו HEVC או HDR, כשהסרטונים נפתחים באפליקציה שלא תומכת בפורמט. כך האפליקציות יכולות לפעול גם כשמצלמים סרטונים בפורמטים חדשים יותר במכשיר.
התכונה 'המרת קידוד למדיה תואמת' מושבתת כברירת מחדל. כדי לבקש המרת פורמט של מדיה, האפליקציות צריכות להצהיר על יכולות המדיה שלהן. מידע נוסף על הצהרה על יכולות מדיה זמין במאמר המרת קידוד של מדיה תואמת באתר למפתחי Android.
איך זה עובד
התכונה 'המרת קידוד למדיה תואמת' מורכבת משני חלקים עיקריים:
- שירותי המרת קידוד במסגרת המדיה: השירותים האלה ממירים קבצים מפורמט אחד לפורמט אחר באמצעות חומרה, כדי להשיג חביון נמוך והמרות באיכות גבוהה. הפונקציונליות הזו כוללת את Transcoding API, את שירות הקידוד מחדש, פלאגין OEM למסננים מותאמים אישית ורכיבי חומרה. פרטים נוספים זמינים במאמר סקירה כללית על הארכיטקטורה.
- תכונת המרת פורמטים של מדיה שמתאימה לספקי מדיה: הרכיב הזה נמצא בספקי מדיה, והוא מיירט אפליקציות שמנסות לגשת לקובצי מדיה. הוא מציג את הקובץ המקורי או קובץ שעבר המרת פורמט, בהתאם ליכולות המוצהרות של האפליקציה. אם האפליקציה תומכת בפורמט של קובץ המדיה, לא נדרש טיפול מיוחד. אם אפליקציה לא תומכת בפורמט, המסגרת ממירה את הקובץ לפורמט ישן יותר, כמו AVC, כשהאפליקציה ניגשת לקובץ.
איור 1 מציג סקירה כללית של תהליך המרת הקידוד של המדיה.
איור 1. סקירה כללית על המרת קידוד למדיה תואמת.
פורמטים נתמכים
התכונה 'המרת קידוד למדיה תואמת' תומכת בהמרות הבאות של פורמטים:
- HEVC (8-bit) to AVC: המרות קודק מתבצעות באמצעות חיבור של פענוח mediacodec אחד וקידוד mediacode אחד.
- HDR10+ (10 ביט) ל-AVC (SDR): המרות מ-HDR ל-SDR מתבצעות באמצעות מופעים של mediacodec ו-vendor plugin hook למופעים של המפענח. מידע נוסף מופיע במאמר בנושא קידוד HDR ל-SDR.
מקורות תוכן נתמכים
תכונת הקידוד מחדש של מדיה תואמת תומכת במדיה שנוצרה במכשיר על ידי אפליקציית המצלמה המקורית של יצרן הציוד המקורי (OEM) ונשמרה בתיקייה DCIM/Camera/
בכרך החיצוני הראשי. התכונה לא תומכת במדיה באחסון משני.
אין תמיכה בתוכן שמועבר למכשירים באמצעות אימייל או כרטיסי SD.
האפליקציות ניגשות לקבצים על סמך נתיבי קבצים שונים. בטבלה הבאה מפורטים נתיבי הקבצים שבהם ההמרה מופעלת או נדחית:
המרת קידוד מופעלת:
- גישה לאפליקציה דרך ממשקי MediaStore API
- גישה לאפליקציות דרך ממשקי API של נתיבי קבצים ישירים, כולל Java וקוד מקורי
- גישה לאפליקציות דרך Storage Access Framework (SAF)
- גישה לאפליקציה דרך כוונות של גיליון השיתוף במערכת ההפעלה. (URI של MediaStore בלבד)
- העברת קבצים ב-MTP/PTP מהטלפון למחשב
המרת הקידוד נדחית:
- העברת קובץ ממכשיר על ידי הוצאת כרטיס ה-SD
- העברת קבצים ממכשיר למכשיר באמצעות אפשרויות כמו 'שיתוף בקרבת מקום' או העברה באמצעות Bluetooth.
הוספה של נתיבי קבצים מותאמים אישית לטרנסקוד
יצרני מכשירים יכולים להוסיף נתיבי קבצים לקידוד מחדש של מדיה בספרייה DCIM/
. כל הנתיבים מחוץ לספרייה DCIM/
נדחים.
יכול להיות שתידרשו להוסיף נתיבי קבצים כאלה כדי לעמוד בדרישות של חברות תובלה או בתקנות מקומיות.
כדי להוסיף נתיב קובץ, משתמשים בנתיב הקידוד runtime resource overlay (RRO),
config_supported_transcoding_relative_paths
. דוגמה להוספת נתיב קובץ:
<string-array name="config_supported_transcoding_relative_paths" translatable="false">
<item>DCIM/JCF/</item>
</string-array>
כדי לוודא את נתיבי הקבצים שהוגדרו, משתמשים בפקודה:
adb shell dumpsys activity provider com.google.android.providers.media.module/com.android.providers.media.MediaProvider | head -n 20
סקירה כללית של הארכיטקטורה
בקטע הזה מתוארת הארכיטקטורה של התכונה להמרת קודקים של מדיה.
איור 2. ארכיטקטורה של המרת קידוד למדיה.
ארכיטקטורת המרת הקידוד למדיה מורכבת מהרכיבים הבאים:
- MediaTranscodingManager system API: ממשק שמאפשר ללקוח לתקשר עם שירות MediaTranscoding. מודול MediaProvider משתמש ב-API הזה.
- MediaTranscodingService: שירות מקורי שמנהל חיבורים של לקוחות, מתזמן בקשות המרה ומנהל את הנהלת החשבונות של
TranscodingSessions
. - MediaTranscoder: ספריית Native שמבצעת המרת קידוד. הספרייה הזו מבוססת על מסגרת המדיה NDK כדי להיות תואמת למודולים.
תכונת המרת הקידוד למדיה תואמת רושמת ביומן מדדי המרת קידוד גם בשירות וגם בממיר הקידוד למדיה. הקוד בצד הלקוח והקוד בצד השרת נמצאים במודול MediaProvider כדי לאפשר תיקוני באגים ועדכונים בזמן.
גישה לקבצים
התכונה 'קידוד טרנספורמציה של מדיה תואמת' מבוססת על מערכת הקבצים Filesystem in Userspace (FUSE), שמשמשת לאחסון בהיקף מוגבל. FUSE מאפשר למודול MediaProvider לבדוק פעולות על קבצים במרחב המשתמש, ולשלוט בגישה לקבצים על סמך המדיניות כדי לאשר, לדחות או לצנזר את הגישה.
כשמנסים לגשת לקובץ דרך אפליקציה, דמון FUSE מיירט את הגישה לקריאת הקובץ מהאפליקציה. אם האפליקציה תומכת בפורמט חדש יותר (כמו HEVC), הקובץ המקורי מוחזר. אם האפליקציה לא תומכת בפורמט, הקובץ עובר המרה לפורמט ישן יותר (כמו AVC) או שהוא מוחזר מהמטמון אם יש גרסה שעברה המרה.
בקשה לקבצים שעברו המרה
התכונה 'המרת קידוד למדיה תואמת' מושבתת כברירת מחדל. אפליקציות יכולות לבקש נכסים שעברו המרה באמצעות האפשרויות הבאות:
- מצהירים על פורמטים שלא נתמכים בקובץ המניפסט. לפרטים נוספים, אפשר לעיין במאמרים בנושא הצהרת יכולות במשאב והצהרת יכולות בקוד.
- השבתה של פורמטים נתמכים באמצעות מסגרת התאימות של האפליקציה בזמן הריצה (המשתמשים יכולים גם להשבית את האפשרות הזו לכל אפליקציה בהגדרות).
- פותחים קובץ באמצעות
MediaStore
תוך ציון מפורש של פורמטים לא נתמכים באמצעות ה-APIopenTypedAssetFileDescriptor
.
בהעברות דרך USB (ממכשיר למחשב), המרת הקידוד מושבתת כברירת מחדל, אבל המשתמשים יכולים להפעיל אותה באמצעות המתג המרת סרטונים ל-AVC במסך ההגדרות העדפות USB, כמו שמוצג באיור 3.
איור 3. מחליפים את המצב כדי להפעיל המרת קידוד של מדיה במסך 'העדפות USB'.
הגבלות על בקשות לקבצים שעברו המרה
כדי למנוע מצב שבו בקשות לשינוי קידוד נועלות משאבי מערכת לתקופות ממושכות, האפליקציות שמבקשות סשנים של שינוי קידוד מוגבלות ל:
- 10 סשנים עוקבים
- משך ההפעלה הכולל של שלוש דקות
אם אפליקציה חורגת מכל ההגבלות האלה, המסגרת מחזירה את מתאר הקובץ המקורי.
דרישות לגבי מכשירים
כדי לתמוך בתכונה של המרת קידוד של מדיה תואמת, המכשירים צריכים לעמוד בדרישות הבאות:
- הקידוד בפורמט HEVC מופעל כברירת מחדל באפליקציית המצלמה המקורית של המכשיר
- (מכשירים שתומכים בקידוד מחדש מ-HDR ל-SDR) המכשיר תומך בצילום וידאו ב-HDR
כדי לשפר את ביצועי המכשיר בהמרת קודקים של מדיה, צריך לבצע אופטימיזציה של ביצועי הגישה לקריאה ולכתיבה של חומרת הווידאו והאחסון. כשמגדירים את רכיבי הקודק של המדיה עם עדיפות ששווה ל-1
, רכיבי הקודק צריכים לפעול עם קצב העברת הנתונים הגבוה ביותר שאפשר. מומלץ שביצועי הקידוד מחדש יהיו לפחות 200 פריימים לשנייה. כדי לבדוק את ביצועי החומרה, מריצים את מדד ההשוואה של כלי הקידוד של מדיה בכתובת frameworks/av/media/libmediatranscoding/transcoder/benchmark
.
אימות
כדי לבדוק את התכונה של המרת קידוד מדיה תואמת, מריצים את הבדיקות הבאות של CTS:
android.media.mediatranscoding.cts
android.mediaprovidertranscode.cts
הפעלה של המרת קידוד של מדיה בהיקף גלובלי
כדי לבדוק את מסגרת המרת הקידוד למדיה או את התנהגות האפליקציה עם המרת קידוד, אפשר להפעיל או להשבית את התכונה 'המרת קידוד למדיה תואמת' באופן גלובלי. בדף האפשרויות למפתחים הגדרות > מערכת > מפתח > המרת קודקים של מדיה, מעבירים את המתג ביטול ברירות המחדל של המרת קודקים למצב מופעל, ואז מעבירים את המתג הפעלת המרת קודקים למצב מופעל או מושבת. אם ההגדרה הזו מופעלת, יכול להיות שהמרת קודקים של מדיה תתבצע ברקע באפליקציות אחרות חוץ מהאפליקציה שאתם מפתחים.
בדיקת סטטוס הקידוד הטרנסקוד
במהלך הבדיקה, אפשר להשתמש בפקודה הבאה של ADB shell כדי לבדוק את סטטוס הטרנסקוד, כולל סשנים של טרנסקוד בהווה ובעבר:
adb shell dumpsys media.transcoding
הארכת מגבלת אורך הסרטון
לצורך בדיקה, אפשר להאריך את מגבלת האורך של דקה אחת לסרטון לטרנסקוד באמצעות הפקודה הבאה. יכול להיות שיהיה צורך בהפעלה מחדש אחרי הפעלת הפקודה הזו.
adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>
מקורות וחומרי עזר של AOSP
בהמשך מפורט קוד המקור של AOSP שקשור להמרת קידוד למדיה תואמת.
Transcoding System API (לשימוש של MediaProvider בלבד)
ApplicationMediaCapabilities API
frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
שירות המרת קידוד למדיה
frameworks/av/services/mediatranscoding/
frameworks/av/media/libmediatranscoding/
Native MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder
פלאגין לדוגמה של HDR ל-MediaTranscoder
קוד ליירוט קבצים ולהמרת קידוד ב-MediaProvider
נקודת השוואה של MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder/benchmark
בדיקות CTS
cts/tests/tests/mediatranscoding/
קידוד HDR ל-SDR
כדי לתמוך בקידוד מ-HDR ל-SDR, יצרני מכשירים יכולים להשתמש בתוסף המסנן של Codec 2.0 לדוגמה ב-AOSP, שנמצא ב-/platform/frameworks/av/media/codec2/hidl/plugin/
.
בקטע הזה מוסבר איך פועל פלאגין המסננים, איך מטמיעים אותו ואיך בודקים אותו.
אם במכשיר אין תוסף שתומך בקידוד HDR ל-SDR, אפליקציה שמנסה לגשת לסרטון HDR מקבלת את מתאר הקובץ המקורי, ללא קשר ליכולות המדיה של האפליקציה שמוצהרות במניפסט.
איך זה עובד
בקטע הזה מתואר ההתנהגות הכללית של פלאגין המסנן Codec 2.0.
רקע
ב-Android יש הטמעה של שכבת התאמה בין הממשק Codec 2.0 לבין הממשק android.hardware.media.c2
HAL ב-android::hardware::media::c2
. ב-AOSP יש מנגנון wrapper לתוספי סינון, שעוטף את המפענחים יחד עם תוספי הסינון.
MediaCodec
מזהה את הרכיבים העטופים האלה כמפענחים עם תכונות סינון.
סקירה כללית
המחלקות FilterWrapper
מקבלות רכיבי codec של ספקים ומחזירות רכיבי codec עטופים לשכבת ההתאמה FilterWrapper
.media.c2
הסיווג FilterWrapper
נפרס דרך libc2filterplugin.so
API של FilterWrapper::Plugin
ומתעד מסננים זמינים מהפלאגין. בזמן היצירה, FilterWrapper
יוצר מופע של כל המסננים הזמינים. רק מסננים שמשנים את המאגר מתחילים לפעול בהתחלה.
איור 4. ארכיטקטורת פלאגין לסינון.
ממשק של פלאגין לסינון
ממשק
FilterPlugin.h
מגדיר את ממשקי ה-API הבאים לחשיפת המסננים:
std::shared_ptr<C2ComponentStore>getComponentStore()
הפונקציה מחזירה אובייקט
C2ComponentStore
שמכיל מסננים. הערך הזה שונה ממה שמוצג בהטמעה של Codec 2.0 של הספק. בדרך כלל, המאגר הזה מכיל רק את המסננים שמשמשים את המחלקהFilterWrapper
.bool describe(C2String name, Descriptor *desc)
תיאור המסננים בנוסף למה שזמין מ-
C2ComponentStore
. התיאורים הבאים מוגדרים:-
controlParam
: פרמטרים ששולטים בהתנהגות של המסננים. לדוגמה, כדי להמיר HDR ל-SDR, פרמטר הבקרה הוא פונקציית ההעברה של היעד. affectedParams
: פרמטרים שמושפעים מפעולות הסינון. לדוגמה, בממיר טונים מ-HDR ל-SDR, הפרמטרים שמושפעים הם היבטי הצבע.
-
bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)
הפונקציה מחזירה
true
אם רכיב המסנן משנה את המאגר. לדוגמה, המסנן tone-mapping מחזירtrue
אם פונקציית ההעברה של היעד היא SDR ופונקציית ההעברה של הקלט היא HDR (HLG או PQ).
פרטים של FilterWrapper
בקטע הזה מתוארים פרטים על המחלקה FilterWrapper
.
יצירה
הרכיב העוטף יוצר מופע של המפענח הבסיסי ושל כל המסננים המוגדרים בזמן היצירה.
שאילתה והגדרה
הרכיב העוטף מפריד בין פרמטרים נכנסים לבין שאילתות או בקשות הגדרה, בהתאם לתיאור המסנן. לדוגמה, הגדרת פרמטר הבקרה של המסנן מנותבת למסנן המתאים, והפרמטרים המושפעים מהמסננים מופיעים בשאילתות (במקום לקרוא מהפענוח פרמטרים שלא הושפעו).
איור 5. שאילתה והגדרה.
התחלה
בתחילת התהליך, הרכיב העוטף מפעיל את המפענח ואת כל המסננים שמשנים את המאגרים. אם לא מופעל מסנן, הרכיב העוטף מפעיל את המפענח ואת מאגרי הנתונים הזמניים של העברת הנתונים, ושולח פקודות למפענח עצמו.
טיפול במאגר נתונים זמני
איור 6. טיפול במאגר נתונים זמני.
מאגרי נתונים זמניים שנמצאים בתור למפענח העטוף מועברים למפענח הבסיסי. הרכיב העוטף מקבל את מאגר הפלט מהמפענח באמצעות קריאה חוזרת (callback) של onWorkDone_nb()
, ואז מוסיף אותו לתור של המסננים. מאגר הפלט הסופי מהמסנן האחרון מדווח ללקוח.
כדי שהטיפול במאגר הזה יפעל, הרכיב העוטף צריך להגדיר את C2PortBlockPoolsTuning
למסנן האחרון, כך שמאגרי הפלט של המסגרת יגיעו ממאגר הבלוקים הצפוי.
עצירה, איפוס ושחרור
בנקודת העצירה, הרכיב העוטף מפסיק את המפענח ואת כל המסננים המופעלים שהופעלו. במהלך איפוס ושחרור, כל הרכיבים מאופסים או משוחררים, בלי קשר לשאלה אם הם מופעלים או לא.
הטמעה של פלאגין מסנן לדוגמה
כדי להפעיל את הפלאגין:
- מטמיעים את הממשק
FilterPlugin
בספרייה ומשחררים אותו ב-/vendor/lib[64]/libc2filterplugin.so.
- אם צריך, מוסיפים הרשאות נוספות ל-
mediacodec.te
. - מעדכנים את שכבת ההתאמה ל-Android 12 ובונים מחדש את שירות
media.c2
.
בדיקת הפלאגין
כדי לבדוק את הפלאגין לדוגמה:
- לבנות מחדש את המכשיר ולהפעיל אותו.
מריצים את הפקודה הבאה כדי ליצור את תוסף הדוגמה:
m sample-codec2-filter-plugin
מציבים מחדש את המכשיר ומשנים את השם של תוסף הספק כך ששירות הקודק יזהה אותו.
adb root adb remount adb reboot adb wait-for-device adb root adb remount adb push /out/target/<...>/lib64/sample-codec2-filter-plugin.so \ /vendor/lib64/libc2filterplugin.so adb push /out/target/<...>/lib/sample-codec2-filter-plugin.so \ /vendor/lib/libc2filterplugin.so adb reboot