אנדרואיד 10 מציגה ממשקי API לניהול חיץ אופציונליים של מצלמה HAL3 המאפשרים לך ליישם לוגיקה של ניהול מאגר כדי להשיג זיכרון שונה וללכוד פשרות חביון ביישומי HAL של מצלמה.
המצלמה HAL דורשת N בקשות (כאשר N שווה לעומק הצינור ) בתור בצינור שלה, אך לעתים קרובות היא אינה דורשת את כל N סטים של מאגרי פלט בו-זמנית.
לדוגמה, ל-HAL עשויות להיות שמונה בקשות בתור בצנרת, אך היא דורשת רק מאגרי פלט עבור שתי הבקשות בשלבים האחרונים של הצינור. במכשירים המריצים אנדרואיד 9 ומטה, מסגרת המצלמה מקצה מאגרים כאשר הבקשה ממוקמת בתור ב-HAL כך שייתכן שיש שש קבוצות של מאגרים ב-HAL שאינן בשימוש. באנדרואיד 10, ממשקי ה-API של ניהול מאגר של המצלמה HAL3 מאפשרים ניתוק של מאגרי הפלט כדי לפנות את שש קבוצות ה-buffers. זה יכול להוביל לחיסכון של מאות מגה בייט בזיכרון במכשירים מתקדמים ויכול להועיל גם למכשירים עם זיכרון נמוך.
איור 1 מציג תרשים של ממשק ה-HAL של המצלמה עבור מכשירים עם אנדרואיד 9 ומטה. איור 2 מציג את ממשק ה-HAL של המצלמה באנדרואיד 10 עם ממשקי ה-API לניהול מאגר HAL3 של המצלמה.
איור 1. ממשק HAL למצלמה באנדרואיד 9 ומטה
איור 2. ממשק HAL למצלמה באנדרואיד 10 באמצעות ממשקי API לניהול מאגר
הטמעת ממשקי API לניהול מאגר
כדי ליישם את ממשקי API לניהול מאגר, ה-HAL של המצלמה חייב:
- יישם HIDL
ICameraDevice@3.5
. - הגדר את מפתח מאפייני המצלמה
android.info.supportedBufferManagementVersion
ל-HIDL_DEVICE_3_5
.
המצלמה HAL משתמשת בשיטות requestStreamBuffers
ו- returnStreamBuffers
ב- ICameraDeviceCallback.hal
כדי לבקש ולהחזיר מאגרים. ה-HAL חייב גם ליישם את שיטת signalStreamFlush
ב- ICameraDeviceSession.hal
כדי לאותת ל-HAL של המצלמה להחזיר מאגרים.
requestStreamBuffers
השתמש בשיטת requestStreamBuffers
כדי לבקש מאגרים ממסגרת המצלמה. בעת שימוש בממשקי ה-API של ניהול מאגר HAL3 של המצלמה, בקשות לכידה ממסגרת המצלמה אינן מכילות מאגרי פלט, כלומר, השדה bufferId
ב- StreamBuffer
הוא 0
. לכן, ה-HAL של המצלמה חייב להשתמש ב- requestStreamBuffers
כדי לבקש מאגרים ממסגרת המצלמה.
שיטת requestStreamBuffers
מאפשרת למתקשר לבקש מאגרים מרובים מזרמי פלט מרובים בשיחה אחת, מה שמאפשר פחות שיחות HIDL IPC. עם זאת, שיחות לוקחות יותר זמן כאשר מתבקשים יותר מאגרים בו-זמנית וזה עלול להשפיע לרעה על זמן האחזור הכולל של הבקשה לתוצאה. כמו כן, מכיוון שקריאות ל- requestStreamBuffers
בשירות המצלמה, מומלץ שה-HAL של המצלמה ישתמש בשרשור ייעודי בעדיפות גבוהה כדי לבקש מאגרים.
אם בקשת מאגר נכשלת, המצלמה HAL חייבת להיות מסוגלת לטפל כראוי בשגיאות לא קטלניות. הרשימה הבאה מתארת סיבות נפוצות לכך שבקשות מאגר נכשלות וכיצד יש לטפל בהן על ידי המצלמה HAL.
- האפליקציה מתנתקת מזרם הפלט: זוהי שגיאה לא קטלנית. המצלמה HAL צריכה לשלוח
ERROR_REQUEST
עבור כל בקשת לכידה המכוונת לזרם מנותק ולהיות מוכנה לעבד בקשות עוקבות כרגיל. - פסק זמן: זה יכול להתרחש כאשר אפליקציה עסוקה בעיבוד אינטנסיבי תוך שמירה על כמה מאגרים. המצלמה HAL צריכה לשלוח
ERROR_REQUEST
עבור בקשות לכידה שלא ניתן למלא עקב שגיאת זמן קצוב ולהיות מוכנה לעבד בקשות עוקבות כרגיל. - מסגרת המצלמה מכינה תצורת זרם חדשה: ה-HAL של המצלמה צריך להמתין עד להשלמת שיחת
configureStreams
הבאה לפני שתקרא שובrequestStreamBuffers
. - ה-HAL של המצלמה הגיע למגבלת המאגר שלו (שדה
maxBuffers
): ה-HAL של המצלמה צריך להמתין עד שהוא יחזיר לפחות מאגר אחד מהזרם לפני שיקרא שובrequestStreamBuffers
.
returnStreamBuffers
השתמש בשיטת returnStreamBuffers
כדי להחזיר מאגרים נוספים למסגרת המצלמה. ה-HAL של המצלמה מחזיר בדרך כלל מאגרים למסגרת המצלמה באמצעות שיטת processCaptureResult
, אך הוא יכול לתת חשבון רק לבקשות צילום שנשלחו ל-HAL של המצלמה. עם שיטת requestStreamBuffers
, יישום ה-HAL של המצלמה יכול לשמור על יותר מאגרים ממה שהתבקש על ידי מסגרת המצלמה. זה הזמן שבו יש להשתמש בשיטת returnStreamBuffers
. אם יישום HAL לעולם לא מחזיק יותר מאגרים מהמבוקש, יישום HAL של המצלמה אינו צריך לקרוא לשיטת returnStreamBuffers
.
signalStreamFlush
שיטת signalStreamFlush
נקראת על ידי מסגרת המצלמה כדי להודיע למצלמה HAL להחזיר את כל המאגרים בהישג יד. זה נקרא בדרך כלל כאשר מסגרת המצלמה עומדת לקרוא ל- configureStreams
ועליה לנקז את צינור לכידת המצלמה. בדומה לשיטת returnStreamBuffers
, אם יישום HAL של מצלמה אינו מחזיק יותר מאגרים מהמבוקש, ניתן לבצע יישום ריק של שיטה זו.
לאחר שמסגרת המצלמה קוראת signalStreamFlush
, המסגרת מפסיקה לשלוח בקשות לכידה חדשות ל-HAL של המצלמה עד שכל המאגרים יוחזרו למסגרת המצלמה. כאשר כל המאגרים מוחזרים, קריאות השיטה requestStreamBuffers
נכשלות, ומסגרת המצלמה יכולה להמשיך את עבודתה במצב נקי. מסגרת המצלמה קוראת לשיטת configureStreams
או processCaptureRequest
. אם מסגרת המצלמה קוראת לשיטת configureStreams
, ה-HAL של המצלמה יכול להתחיל לבקש שוב מאגרים לאחר שהקריאה ל- configureStreams
תחזור בהצלחה. אם מסגרת המצלמה קוראת לשיטת processCaptureRequest
, המצלמה HAL יכולה להתחיל לבקש מאגרים במהלך קריאת processCaptureRequest
.
הסמנטיקה שונה עבור שיטת signalStreamFlush
ושיטת flush
. כאשר שיטת flush
נקראת, ה-HAL יכול לבטל בקשות לכידה ממתינות עם ERROR_REQUEST
כדי לנקז את הצינור בהקדם האפשרי. כאשר קוראים לשיטת signalStreamFlush
, ה-HAL חייב לסיים את כל בקשות הלכידה הממתינות בדרך כלל ולהחזיר את כל המאגרים למסגרת המצלמה.
הבדל נוסף בין שיטת signalStreamFlush
לשיטות אחרות הוא ש- signalStreamFlush
היא שיטת HIDL חד-כיוונית , מה שאומר שמסגרת המצלמה עשויה להתקשר לממשקי API חוסמים אחרים לפני שה-HAL יקבל את קריאת signalStreamFlush
. המשמעות היא ששיטת signalStreamFlush
ושיטות אחרות (במיוחד שיטת configureStreams
) עשויות להגיע ל-HAL של המצלמה בסדר שונה מהסדר שהם נקראו במסגרת המצלמה. כדי לטפל בבעיה אסינכרונית זו, השדה streamConfigCounter
נוסף ל- StreamConfiguration
והתווסף כארגומנט לשיטת signalStreamFlush
. יישום ה-HAL של המצלמה צריך להשתמש בארגומנט streamConfigCounter
כדי לקבוע אם קריאת signalStreamFlush
מגיעה מאוחר יותר מהקריאה המתאימה ל- configureStreams
. ראה איור 3 לדוגמא.
איור 3. כיצד המצלמה HAL צריכה לזהות ולטפל בשיחות signalStreamFlush שמגיעות באיחור
שינויים בהתנהגות בעת הטמעת ממשקי API לניהול מאגר
בעת שימוש בממשקי ה-API של ניהול מאגר כדי ליישם את לוגיקה של ניהול מאגר, שקול את השינויים הבאים בהתנהגות האפשרית ביישום HAL של המצלמה והמצלמה:
בקשות לכידה מגיעות ל-HAL של המצלמה מהר יותר ובתדירות גבוהה יותר: ללא ממשקי API לניהול מאגר, מסגרת המצלמה מבקשת מאגרי פלט עבור כל בקשת לכידה לפני שליחת בקשת לכידה ל-HAL של המצלמה. בעת שימוש בממשקי API לניהול מאגר, מסגרת המצלמה כבר לא צריכה לחכות למאגרים ולכן יכולה לשלוח בקשות לכידה אל המצלמה HAL מוקדם יותר.
כמו כן, ללא ממשקי API לניהול מאגר, מסגרת המצלמה מפסיקה לשלוח בקשות לכידה אם אחד מזרמי הפלט של בקשת הלכידה הגיע למספר המרבי של מאגרים שה-HAL יכול להחזיק בו-זמנית (ערך זה מוגדר על ידי ה-HAL של המצלמה ב- שדה
HalStream::maxBuffers
בערך ההחזרה של קריאה שלconfigureStreams
). עם ממשקי ה-API של ניהול מאגר, התנהגות החמצה הזו אינה קיימת יותר, והטמעת HAL של המצלמה אינה יכולה לקבל קריאותprocessCaptureRequest
כאשר ל-HAL יש יותר מדי בקשות לכידה בתור.זמן האחזור של שיחות
requestStreamBuffers
משתנה באופן משמעותי: ישנן סיבות רבות לכך ששיחה שלrequestStreamBuffers
עשויה להימשך זמן רב יותר מהממוצע. לדוגמה:- עבור כמה מאגרים ראשונים של זרם חדש שנוצר, שיחות עשויות להימשך זמן רב יותר מכיוון שהמכשיר צריך להקצות זיכרון.
- ההשהיה הצפויה גדלה ביחס למספר המאגרים המבוקשים בכל שיחה.
- האפליקציה מחזיקה מאגרים והיא עסוקה בעיבוד. זה עלול לגרום להאטה של בקשות מאגר או להגיע לזמן קצוב בגלל מחסור במאגרים או מעבד תפוס.
אסטרטגיות ניהול מאגר
ממשקי API לניהול מאגר מאפשרים ליישם סוגים שונים של אסטרטגיות ניהול מאגר. חלק מהדוגמאות הן:
- תואם לאחור: ה-HAL מבקש מאגרים עבור בקשת לכידה במהלך קריאת
processCaptureRequest
. אסטרטגיה זו אינה מספקת חיסכון בזיכרון, אך יכולה לשמש כיישום ראשון של ממשקי ה-API לניהול מאגר, הדורשים מעט מאוד שינויים בקוד ב-HAL הקיים של המצלמה. - חיסכון מרבי בזיכרון: המצלמה HAL מבקשת רק מאגרי פלט מיד לפני שיש צורך במילוי אחד. אסטרטגיה זו מאפשרת חיסכון מירבי בזיכרון. החיסרון הפוטנציאלי הוא יותר תקלה בצנרת המצלמה כאשר בקשות מאגר לוקחות זמן בלתי רגיל לסיום.
- מאוחסן במטמון: המצלמה HAL מאחסנת כמה מאגרים כך שסביר יותר שהוא יושפע מבקשת מאגר איטית מדי פעם.
המצלמה HAL יכולה לאמץ אסטרטגיות שונות עבור מקרי שימוש מסוימים, למשל, שימוש באסטרטגיית שמירת הזיכרון המקסימלית עבור מקרי שימוש המשתמשים בהרבה זיכרון ושימוש באסטרטגיה התואמת לאחור עבור מקרי שימוש אחרים.
יישום לדוגמה במצלמה החיצונית HAL
המצלמה החיצונית HAL הוצגה באנדרואיד 9 וניתן למצוא אותה בעץ המקור בכתובת hardware/interfaces/camera/device/3.5/
. באנדרואיד 10, הוא עודכן כך שיכלול את ExternalCameraDeviceSession.cpp
, יישום של ממשק API לניהול מאגר. מצלמה חיצונית HAL זו מיישמת את אסטרטגיית החיסכון המקסימלית בזיכרון המוזכרת באסטרטגיות ניהול מאגר בכמה מאות שורות של קוד C++.