מנהור מולטימדיה, שנקרא גם מצב מנהור, מאפשר לנתוני וידאו דחוסים לעבור דרך מפענח וידאו בחומרה ישירות לתצוגה, בלי לעבור עיבוד על ידי קוד האפליקציה או קוד מסגרת Android. הקוד הספציפי למכשיר שמתחת ל-Android stack קובע אילו פריים של סרטונים יישלחו לתצוגה ומתי הם יישלחו, על ידי השוואה בין חותמות הזמן של הצגת פריים של סרטונים לבין אחד מהסוגים הבאים של שעון פנימי:
להפעלת סרטונים על פי דרישה ב-Android 5 ואילך, נדרש שעון
AudioTrackמסונכרן עם חותמות הזמן של הצגת האודיו שמועברות על ידי האפליקציהלהפעלת שידור חי ב-Android מגרסה 11 ואילך, נדרש שעון ייחוס של תוכנית (PCR) או שעון זמן מערכת (STC) שמופעל על ידי מקלט
רקע
הפעלת סרטון במצב ללא מנהור ב-Android מודיעה לאפליקציה כשפריים של סרטון דחוס מפוענח. לאחר מכן האפליקציה משחררת את פריים הווידאו המפוענח לתצוגה כדי לעבד אותו באותו זמן שעון מערכת כמו פריים האודיו התואם, מאחזרת מופעים היסטוריים של AudioTimestamp כדי לחשב את התזמון הנכון.
הפעלת סרטונים בטכנולוגיית טאנלינג עוקפת את קוד האפליקציה ומצמצמת את מספר התהליכים שפועלים על הסרטון, ולכן יכולה לספק עיבוד יעיל יותר של סרטונים, בהתאם להטמעה של יצרן ציוד מקורי (OEM). בנוסף, הוא יכול לספק קצב פריימים וסנכרון מדויקים יותר של הווידאו לשעון שנבחר (PRC, STC או אודיו) על ידי הימנעות מבעיות תזמון שנובעות מהטיה פוטנציאלית בין התזמון של בקשות Android לעיבוד הווידאו לבין התזמון של סנכרון אנכי אמיתי של החומרה. עם זאת, טכנולוגיית המנהור יכולה גם להפחית את התמיכה באפקטים של GPU, כמו טשטוש או פינות מעוגלות בחלונות של תמונה בתוך תמונה (PiP), כי המאגרים עוקפים את מחסנית הגרפיקה של Android.
בתרשים הבא מוצג איך טכנולוגיית המנהור מפשטת את תהליך הפעלת הווידאו.

איור 1. השוואה בין תהליכי הפעלת סרטונים ללא מנהור ולבין תהליכי הפעלת סרטונים עם מנהור.
למפתחי אפליקציות
רוב מפתחי האפליקציות משתמשים בספרייה להטמעה של הפעלת תוכן, ולכן ברוב המקרים ההטמעה דורשת רק הגדרה מחדש של הספרייה להפעלת תוכן במנהור. כדי להטמיע נגן וידאו עם מנהור ברמה נמוכה, צריך לפעול לפי ההוראות הבאות.
כדי להפעיל סרטונים על פי דרישה ב-Android מגרסה 5 ואילך:
יוצרים מכונת
SurfaceView.יוצרים מכונת
audioSessionId.יוצרים מכונות
AudioTrackו-MediaCodecעם המכונהaudioSessionIdשנוצרה בשלב 2.מעבירים נתוני אודיו לתור של
AudioTrackעם חותמת הזמן של המצגת עבור מסגרת האודיו הראשונה בנתוני האודיו.
כדי להפעיל שידור חי ב-Android מגרסה 11 ואילך:
יוצרים מכונת
SurfaceView.קבלת מופע של
avSyncHwIdמ-Tuner.יוצרים מכונות
AudioTrackו-MediaCodecעם מכונתavSyncHwIdשנוצרה בשלב 2.
קטעי הקוד הבאים מציגים את תהליך הקריאה ל-API:
aab.setContentType(AudioAttributes.CONTENT_TYPE_MOVIE);
// configure for audio clock sync
aab.setFlag(AudioAttributes.FLAG_HW_AV_SYNC);
// or, for tuner clock sync (Android 11 or higher)
new tunerConfig = TunerConfiguration(0, avSyncId);
aab.setTunerConfiguration(tunerConfig);
if (codecName == null) {
return FAILURE;
}
// configure for audio clock sync
mf.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);
// or, for tuner clock sync (Android 11 or higher)
mf.setInteger(MediaFormat.KEY_HARDWARE_AV_SYNC_ID, avSyncId);
התנהגות של הפעלת וידאו על פי דרישה
הפעלת וידאו לפי דרישה במנהור קשורה באופן מרומז להפעלת AudioTrack, ולכן התנהגות ההפעלה של וידאו במנהור עשויה להיות תלויה בהתנהגות ההפעלה של אודיו.
ברוב המכשירים, כברירת מחדל, פריים של סרטון לא מוצג עד שהפעלת האודיו מתחילה. עם זאת, יכול להיות שהאפליקציה תצטרך להציג פריים של וידאו לפני שתתחיל להפעיל את האודיו, למשל כדי להראות למשתמש את המיקום הנוכחי של הסרטון בזמן החיפוש.
כדי לציין שצריך לעבד את המסגרת הראשונה של הסרטון בתור ברגע שהיא מפוענחת, מגדירים את הפרמטר
PARAMETER_KEY_TUNNEL_PEEKלערך1. כשמסדרים מחדש בתור פריימים של סרטון דחוס (למשל, כשקיימים פריימים מסוג B), זה אומר שהפריים הראשון של הסרטון שמוצג צריך להיות תמיד פריים מסוג I.אם אתם לא רוצים שהפריים הראשון של הסרטון שנוסף לתור יוצג עד שתתחיל ההפעלה של האודיו, צריך להגדיר את הפרמטר הזה לערך
0.אם הפרמטר הזה לא מוגדר, יצרן ה-OEM קובע את אופן הפעולה של המכשיר.
כשלא מסופקים נתוני אודיו ל-
AudioTrackוהמאגרים ריקים (חוסר נתוני אודיו), הפעלת הווידאו נעצרת עד שייכתבו עוד נתוני אודיו, כי שעון האודיו לא מתקדם יותר.במהלך ההפעלה, יכול להיות שיופיעו אי-רציפויות בחותמות הזמן של הצגת האודיו, שהאפליקציה לא יכולה לתקן. במקרים כאלה, יצרן הציוד המקורי מתקן פערים שליליים על ידי השהיית הפריימים הנוכחיים של הסרטון, ופערים חיוביים על ידי השמטת פריימים של הסרטון או הוספת פריימים של אודיו שקט (בהתאם להטמעה של יצרן הציוד המקורי). מיקום הפריימים
AudioTimestampלא גדל עבור פריימים של אודיו שקט שמוסיפים.
רצף הפעולות של דילוג מדויק
התכונה 'דילוג מדויק' מאפשרת לכם למצוא נקודה ספציפית בסרטון. בניגוד לחיפוש לפי פריימים מרכזיים, שבו המערכת עוברת רק ל-I-frame הקרוב ביותר ויכולה לסטות ממיקום היעד בכמה שניות, חיפוש מדויק מציג את הסרטון בחותמת הזמן המדויקת שנדרשה. הקפדה על רצף ה-API הספציפי הזה מאפשרת לאפליקציה לבצע טעינה מראש של מודעות ברקע וסנכרון תזמון בצורה חלקה. כך מוודאים שפריים היעד יוצג באופן מיידי כשההפעלה תתחדש.
כדי לבצע חיפוש מדויק, פועלים לפי סדר הביצוע שמוצג באיור 2:
איור 2. רצף הפעולות לדילוג מדויק.
פרטים עיקריים:
ביצוע מקביל: אפשר להריץ שלבים בתוך תיבת
parאחת במקביל. לדוגמה, שיחות וידאו ב-MediaCodecהן נפרדות מ-AudioTrack.תלויות עוקבות: כל הפעולות בתיבה
parהראשונה צריכות להתבצע לפני שמתקדמים לתיבהparהשנייה. באופן ספציפי, האפליקציה צריכה לוודא ש-AudioTrack.writeומאגרי נתונים זמניים בסרטוןMediaCodecמתווספים לתור לפני הקריאה ל-AudioTrack.play.
רצף הפעולה של הפעלת סרטון במהירות משתנה
הפעלה במהירות משתנה מאפשרת לכם להפעיל סרטון במהירות גבוהה או נמוכה יותר מהמהירות הרגילה. התכונה הזו משמשת בדרך כלל באפליקציות כדי לאפשר למשתמשים לצרוך תוכן מהר יותר (למשל, להפעיל הרצאות או פודקאסטים במהירות של פי 1.5 או פי 2 כדי לחסוך זמן) או לאט יותר (למשל, לנתח מהלכים ספורטיביים או סרטוני הדרכה במהירות של פי 0.5).
כדי להגדיר את המהירות, פועלים לפי סדר ההפעלה שמוצג באיור 3:
איור 3. רצף הפעולות להגדרת המהירות.
ההתנהגויות והדרישות הטכניות הבאות לא מופיעות בתרשים הרצף שבאיור 3:
AudioTrack.getTimestampמחזירה את הערךframePositionעל סמך התדירות המקורית של קלט האודיו. לדוגמה, אם קצב הדגימה של הקלט הוא 44,100 Hz ומהירות ההפעלה היא 2.0x, אחרי הפעלה של 2 שניות, הפונקציהAudioTrack.getTimestampמחזירה את הערךframePositionשל 176,400.אם האפליקציה קוראת ל-
setSpeed(1.5)והפעולה הזו מצליחה, ואז האפליקציה קוראת ל-setSpeed(30)והפעולה הזו נכשלת, ההפעלה נשארת במהירות של פי 1.5.אם האודיו מושתק (באמצעות
setVolume), האפליקציה עדיין נדרשת לשלוח מאגרי אודיו כי פריימים של וידאו עוברים רינדור על סמך מיקום האודיו.גובה הצליל של האודיו נשמר כשמשנים את המהירות.
מהירות ההפעלה לא מושפעת מפעולות הפעלה אחרות.
דוגמה 1: אם מהירות ההפעלה היא 1.5x והסרטון
AudioTrackמושהה, המהירות נשארת 1.5x אחרי שממשיכים את ההפעלה שלAudioTrack.דוגמה 2: אם מהירות ההפעלה היא x1.5 והמשתמש עובר ל-PTS אחר, לפי איור 2, ההפעלה נשארת במהירות x1.5.
כדי לוודא שכל הפריים מפוענח בזמן כדי לעבור רינדור במהירות שנבחרה, צריך להגדיר את
KEY_OPERATING_RATEכך שיתאים למכפלה של קצב הפריימים של הסרטון ומהירות ההפעלה. אם הערך שלKEY_OPERATING_RATEלא מוגדר מספיק גבוה, יכול להיות שהקודק לא יפענח את הפריימים מספיק מהר, וזה יגרום להשמטת פריימים לא מכוונת במהלך ההפעלה.- לדוגמה: אם קצב הפריימים המקורי של התוכן הוא 60 fps, ומהירות ההפעלה היא x2, צריך להגדיר את
KEY_OPERATING_RATEל-120.
- לדוגמה: אם קצב הפריימים המקורי של התוכן הוא 60 fps, ומהירות ההפעלה היא x2, צריך להגדיר את
הגדרת מהירות שוב ושוב עם מהירויות שונות שנתמכות לא אמורה להפעיל שגיאות, והתנהגות ההפעלה אחרי הקריאה האחרונה צריכה להיות זהה להתנהגות ההפעלה אם המהירות מוגדרת רק פעם אחת, למהירות האחרונה שהוגדרה.
ליצרני מכשירים
הגדרות אישיות
יצרני ציוד מקורי (OEM) צריכים ליצור מפענח וידאו נפרד כדי לתמוך בהפעלת וידאו במנהור.
המפענח הזה צריך לפרסם שהוא מסוגל להפעיל תוכן בשיטת טאנלינג בקובץ media_codecs.xml:
<Feature name="tunneled-playback" required="true"/>
כשמוגדר מופע MediaCodec עם מנהור עם מזהה של סשן אודיו, הוא שולח שאילתה אל AudioFlinger לגבי מזהה HW_AV_SYNC הזה:
if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
int sessionId = 0;
try {
sessionId = (Integer)entry.getValue();
}
catch (Exception e) {
throw new IllegalArgumentException("Wrong Session ID Parameter!");
}
keys[i] = "audio-hw-sync";
values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
}
במהלך השאילתה הזו, AudioFlinger מאחזר את מזהה HW_AV_SYNC ממכשיר האודיו הראשי ומשייך אותו באופן פנימי למזהה של סשן האודיו:
audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC);
AudioParameter param = AudioParameter(String8(reply));
int hwAVSyncId;
param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), hwAVSyncId);
אם כבר נוצר מופע של AudioTrack, המזהה HW_AV_SYNC מועבר לזרם הפלט עם אותו מזהה של סשן אודיו. אם הוא עדיין לא נוצר, המזהה HW_AV_SYNC מועבר לזרם הפלט במהלך היצירה של AudioTrack. הפעולה הזו מתבצעת על ידי השרשור של ההפעלה:
mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);
המזהה HW_AV_SYNC, בין אם הוא תואם לסטרימינג של פלט אודיו או להגדרה של Tuner, מועבר לרכיב OMX או Codec2 כדי שקוד ה-OEM יוכל לשייך את הקודק לסטרימינג המתאים של פלט האודיו או לסטרימינג של הטיונר.
במהלך הגדרת הרכיב, רכיב ה-OMX או Codec2 צריך להחזיר ידית פס צד שאפשר להשתמש בה כדי לשייך את הקודק לשכבת Hardware Composer (HWC). כשהאפליקציה משייכת משטח ל-MediaCodec, ה-handle של פס הצד הזה מועבר ל-HWC דרך MediaCodec, שמגדיר את השכבה כשכבת פס צד.SurfaceFlinger
err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
if (err != OK) {
ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", sidebandHandle, err);
return err;
}
ה-HWC אחראי לקבלת מאגרי תמונות חדשים מפלט ה-codec בזמן המתאים, מסונכרנים עם זרם פלט האודיו המשויך או עם שעון הייחוס של תוכנית הטיונר, הרכבת המאגרים עם התוכן הנוכחי של שכבות אחרות והצגת התמונה שמתקבלת. הפעולה הזו מתבצעת בנפרד מהמחזור הרגיל של הכנה והגדרה. הקריאות להכנה ולהגדרה מתבצעות רק כששכבות אחרות משתנות, או כשמאפיינים של שכבת הפס הצדדי (כמו מיקום או גודל) משתנים.
OMX
רכיב של מפענח מנהור צריך לתמוך בפעולות הבאות:
הגדרת הפרמטר המורחב
OMX.google.android.index.configureVideoTunnelMode, שמשתמש במבנהConfigureVideoTunnelModeParamsכדי להעביר את המזההHW_AV_SYNCשמשויך למכשיר פלט האודיו.הגדרת הפרמטר
OMX_IndexConfigAndroidTunnelPeekשמורה לקודק אם להציג או לא להציג את פריים הווידאו המפוענח הראשון, בלי קשר לשאלה אם הפעלת האודיו התחילה.שליחת האירוע
OMX_EventOnFirstTunnelFrameReadyכשמסגרת הווידאו הראשונה שמועברת במנהור מפוענחת ומוכנה להצגה.
ההטמעה של AOSP מגדירה את מצב המנהור ב-ACodec דרך OMXNodeInstance, כמו שמוצג בקטע הקוד הבא:
OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
"OMX.google.android.index.configureVideoTunnelMode");
OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
ConfigureVideoTunnelModeParams tunnelParams;
InitOMXParams(&tunnelParams);
tunnelParams.nPortIndex = portIndex;
tunnelParams.bTunneled = tunneled;
tunnelParams.nAudioHwSync = audioHwSync;
err = OMX_SetParameter(mHandle, index, &tunnelParams);
err = OMX_GetParameter(mHandle, index, &tunnelParams);
sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
אם הרכיב תומך בהגדרה הזו, הוא צריך להקצות לרכיב הקודק הזה נקודת אחיזה של ערוץ צדדי ולהעביר אותה חזרה דרך חבר pSidebandWindow כדי שמערכת HWC תוכל לזהות את רכיב הקודק המשויך. אם הרכיב לא תומך בהגדרה הזו, הוא צריך להגדיר את bTunneled ל-OMX_FALSE.
Codec2
ב-Android מגרסה 11 ואילך, Codec2 תומך בהפעלה במנהור. רכיב הפענוח צריך לתמוך בפעולות הבאות:
הגדרת
C2PortTunneledModeTuning, שכוללת הגדרה של מצב מנהור והעברה שלHW_AV_SYNCשאוחזר ממכשיר פלט האודיו או מהגדרת הטיונר.מתבצעת שאילתה לגבי
C2_PARAMKEY_OUTPUT_TUNNEL_HANDLEכדי להקצות ולאחזר את נקודת האחיזה של פס הצד עבור HWC.טיפול ב-
C2_PARAMKEY_TUNNEL_HOLD_RENDERכשהוא מצורף ל-C2Work, שמורה לקודק לפענח ולסמן את סיום העבודה, אבל לא לעבד את מאגר הפלט עד ש-1) הקודק יקבל הוראה לעבד אותו מאוחר יותר או 2) הפעלת האודיו תתחיל.טיפול ב-
C2_PARAMKEY_TUNNEL_START_RENDER, שמורה לקודק להציג באופן מיידי את הפריים שסומן ב-C2_PARAMKEY_TUNNEL_HOLD_RENDER, גם אם הפעלת האודיו לא התחילה.לא להגדיר את
debug.stagefright.ccodec_delayed_params(מומלץ). אם מגדירים אותה, צריך להגדיר את הערךfalse.
ההטמעה ב-AOSP מגדירה את מצב המנהור ב-CCodec דרך C2PortTunnelModeTuning, כמו שמוצג בקטע הקוד הבא:
if (msg->findInt32("audio-hw-sync", &tunneledPlayback->m.syncId[0])) {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
} else if (msg->findInt32("hw-av-sync-id", &tunneledPlayback->m.syncId[0])) {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::HW_AV_SYNC;
} else {
tunneledPlayback->m.syncType =
C2PortTunneledModeTuning::Struct::sync_type_t::REALTIME;
tunneledPlayback->setFlexCount(0);
}
c2_status_t c2err = comp->config({ tunneledPlayback.get() }, C2_MAY_BLOCK,
failures);
std::vector<std::unique_ptr<C2Param>> params;
c2err = comp->query({}, {C2PortTunnelHandleTuning::output::PARAM_TYPE},
C2_DONT_BLOCK, ¶ms);
if (c2err == C2_OK && params.size() == 1u) {
C2PortTunnelHandleTuning::output *videoTunnelSideband =
C2PortTunnelHandleTuning::output::From(params[0].get());
return OK;
}
אם הרכיב תומך בהגדרה הזו, הוא צריך להקצות לרכיב הקודק הזה נקודת אחיזה של ערוץ צדדי ולהעביר אותה בחזרה דרך C2PortTunnelHandlingTuning כדי שרכיב ה-HWC יוכל לזהות את רכיב הקודק המשויך.
HAL של אודיו
להפעלת וידאו על פי דרישה, ה-Audio HAL מקבל את חותמות הזמן של הצגת האודיו בשורה עם נתוני האודיו בפורמט big-endian בתוך כותרת שנמצאת בתחילת כל בלוק של נתוני אודיו שהאפליקציה כותבת:
struct TunnelModeSyncHeader {
// The 32-bit data to identify the sync header (0x55550002)
int32 syncWord;
// The size of the audio data following the sync header before the next sync
// header might be found.
int32 sizeInBytes;
// The presentation timestamp of the first audio sample following the sync
// header.
int64 presentationTimestamp;
// The number of bytes to skip after the beginning of the sync header to find the
// first audio sample (20 bytes for compressed audio, or larger for PCM, aligned
// to the channel count and sample size).
int32 offset;
}
כדי ש-HWC יעבד פריימים של וידאו בסנכרון עם הפריימים התואמים של האודיו, ה-HAL של האודיו צריך לנתח את כותרת הסנכרון ולהשתמש בחותמת הזמן של ההצגה כדי לסנכרן מחדש את שעון ההפעלה עם עיבוד האודיו. כדי לבצע סנכרון מחדש בזמן השמעה של אודיו דחוס, יכול להיות ששכבת ה-HAL של האודיו תצטרך לנתח מטא-נתונים בתוך נתוני האודיו הדחוס כדי לקבוע את משך ההפעלה שלו.
השהיית התמיכה
ב-Android 5 ומטה אין תמיכה בהשהיה. אפשר להשהות הפעלה של מנהור רק על ידי הרעבת A/V, אבל אם המאגר הפנימי של הווידאו גדול (לדוגמה, יש שנייה אחת של נתונים ברכיב OMX), ההשהיה נראית לא מגיבה.
ב-Android מגרסה 5.1 ואילך, AudioFlinger תומך בהשהיה ובהמשך הפעלה של פלט אודיו ישיר (מנהור). אם שכבת ה-HAL מטמיעה השהיה והפעלה מחדש, השהיה והפעלה מחדש של הרצועה מועברות לשכבת ה-HAL.
רצף הקריאות pause, flush, resume מבוצע על ידי הפעלת קריאות HAL בשרשור ההפעלה (בדומה להעברה).
הצעות להטמעה
HAL של אודיו
ב-Android 11, אפשר להשתמש במזהה הסנכרון של החומרה מ-PCR או מ-STC לסנכרון אודיו/וידאו, כך שנתמך סטרימינג של וידאו בלבד.
ב-Android מגרסה 10 ומטה, למכשירים שתומכים בהפעלת סרטונים בשיטת tunneled צריכים להיות לפחות פרופיל אחד של זרם פלט אודיו עם הדגלים FLAG_HW_AV_SYNC ו-AUDIO_OUTPUT_FLAG_DIRECT בקובץ audio_policy.conf. הדגלים האלה משמשים להגדרת שעון המערכת משעון האודיו.
OMX
ליצרני מכשירים צריך להיות רכיב OMX נפרד להפעלת סרטונים בשיטת ה-tunneling (יצרנים יכולים להשתמש ברכיבי OMX נוספים להפעלת סוגים אחרים של אודיו ווידאו, כמו הפעלה מאובטחת). הרכיב המנהור צריך:
מציינים 0 מאגרי נתונים זמניים (
nBufferCountMin,nBufferCountActual) ביציאה שלו.מטמיעים את התוסף
OMX.google.android.index.prepareForAdaptivePlayback setParameter.מציינים את היכולות שלו בקובץ
media_codecs.xmlומצהירים על התכונה 'הפעלה במנהור'. כדאי גם להבהיר אם יש הגבלות על גודל המסגרת, על היישור או על קצב העברת הנתונים. דוגמה:<MediaCodec name="OMX.OEM_NAME.VIDEO.DECODER.AVC.tunneled" type="video/avc" > <Feature name="adaptive-playback" /> <Feature name="tunneled-playback" required=”true” /> <Limit name="size" min="32x32" max="3840x2160" /> <Limit name="alignment" value="2x2" /> <Limit name="bitrate" range="1-20000000" /> ... </MediaCodec>
אם אותו רכיב OMX משמש לתמיכה בפענוח עם מנהור ובפענוח ללא מנהור, הוא צריך להשאיר את תכונת ההפעלה עם מנהור כלא נדרשת. לכן, גם למפענחים עם מנהור וגם למפענחים בלי מנהור יש את אותן מגבלות יכולת. דוגמה:
<MediaCodec name="OMX._OEM\_NAME_.VIDEO.DECODER.AVC" type="video/avc" >
<Feature name="adaptive-playback" />
<Feature name="tunneled-playback" />
<Limit name="size" min="32x32" max="3840x2160" />
<Limit name="alignment" value="2x2" />
<Limit name="bitrate" range="1-20000000" />
...
</MediaCodec>
Hardware Composer (HWC)
כשמוצגת שכבה עם מנהור (שכבה עם HWC_SIDEBAND compositionType), הערך של sidebandStream בשכבה הוא נקודת האחיזה של פס הצד שהוקצתה על ידי רכיב הווידאו של OMX.
ה-HWC מסנכרן פריימים מפוענחים של וידאו (מרכיב ה-OMX המנהר) עם טראק האודיו המשויך (עם המזהה audio-hw-sync). כשפריים חדש של סרטון הופך להיות הנוכחי, ה-HWC משלב אותו עם התוכן הנוכחי של כל השכבות שהתקבלו במהלך ההכנה או השיחה האחרונה להגדרת המיקום, ומציג את התמונה שמתקבלת.
הקריאות להכנה או להגדרה מתבצעות רק כששכבות אחרות משתנות, או כשמאפיינים של שכבת פס הצד (כמו מיקום או גודל) משתנים.
באיור הבא מוצגת פעולת ה-HWC עם הסינכרונייזר של החומרה (או של הליבה או מנהל ההתקן), כדי לשלב בין פריימים של סרטונים (7ב) לבין הקומפוזיציה האחרונה (7א) לצורך הצגה בזמן הנכון, על סמך האודיו (7ג).

איור 4. מסנכרן חומרה (או ליבה או דרייבר) של HWC.