סטרימינג בו-זמנית ממצלמה

מערכת Android מאפשרת למכשירים לתמוך בסטרימינג בו-זמני של מכשירי מצלמה. לדוגמה, המצב הזה מאפשר למכשיר להפעיל את המצלמה הקדמית ואת המצלמה האחורית בו-זמנית. מ-Android 11, ‏ Camera2 API כולל את השיטות הבאות שאפליקציות יכולות להפעיל כדי לקבוע אם המצלמות תומכות בשידור בו-זמני ואת הגדרות השידור הנתמכות.

  • getConcurrentCameraIds: מקבל את קבוצת השילובים של מזהי מכשירי המצלמה שמחוברים כרגע, שתומכים בהגדרה של סשנים של מכשירי מצלמה בו-זמנית.
  • isConcurrentSessionConfigurationSupported: בודקת אם אפשר להגדיר בו-זמנית את קבוצת מכשירי המצלמה שצוינה ואת הגדרות הסשן התואמות שלהם.

קבוצה של שילובי סטרימינג חובה שצריכים להיות נתמכים במהלך סטרימינג בו-זמני כלולים במאפיין SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS של מאפייני המצלמה של מכשיר המצלמה.

כל מכשיר מצלמה שמפורסם דרך getConcurrentStreamingCameraIds() צריך לתמוך בהגדרות המובטחות הבאות לשידורים בו-זמניים.

יעד 1 יעד 2
סוג גודל מקסימלי סוג גודל מקסימלי תרחישים לדוגמה
YUV s1440p עיבוד סרטונים או תמונות באפליקציה
PRIV s1440p ניתוח של העינית באפליקציה
JPEG s1440p ללא צילום תמונות סטילס בתצוגת המצלמה
YUV / PRIV s720p JPEG s1440p תמונות סטילס רגילות
YUV / PRIV s720p YUV / PRIV s1440p סרטון או עיבוד באפליקציה עם תצוגה מקדימה

מכשירים עם יכולת MONOCHROME (CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES כולל CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) שמריצים Y8 חייבים לתמוך בהחלפת סטרימינג של YUV ב-Y8 בכל השילובים המובטחים של סטרימינג.

s720p מתייחס ל-720p ‏ (1280x720) או לרזולוציה המקסימלית הנתמכת בפורמט הספציפי שמוחזר על ידי StreamConfigurationMap.getOutputSizes(). ‫s1440p מתייחס ל-1440p‏ (1920x1440) או לרזולוציה המקסימלית הנתמכת בפורמט המסוים שמוחזר על ידי StreamConfigurationMap.getOutputSizes(). מכשירים שהיכולות שלהם לא כוללות את ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE חייבים לתמוך לפחות בזרם Y16 אחד, Dataspace::DEPTH ברזולוציית sVGA, במהלך פעולה בו-זמנית, כאשר sVGA היא הרזולוציה הקטנה מבין שתי הרזולוציות הבאות:

  • רזולוציית הפלט המקסימלית לפורמט הנתון
  • 640 x 480

הטמעה

כדי לאפשר לאפליקציות לשלוח שאילתה למכשיר כדי לקבוע אם המצלמות שלו תומכות בסטרימינג בו-זמני, צריך להטמיע את ממשק ה-HAL‏ ICameraProvider@2.6, שכולל את השיטות הבאות:

לעיון בהטמעה לדוגמה של ממשק ICameraProvider@2.6HAL, אפשר לעיין בספריית HAL של המצלמה המדומה בכתובת EmulatedCameraProviderHWLImpl.cpp.

אימות

כדי לבדוק שההטמעה של התכונה הזו פועלת כמו שצריך, משתמשים בבדיקת CTS‏ ConcurrentCameraTest.java. בנוסף, כדאי לבדוק את המצלמות באמצעות אפליקציה שפותחת כמה מצלמות ומפעילה אותן בו-זמנית.

בעיות בהקצאת משאבים

אם רכיבי HAL של המצלמה מפרסמים תמיכה בהפעלה בו-זמנית של מכשירי מצלמה, יכול להיות שיתעוררו בעיות בהקצאת משאבים, במיוחד במקרים שבהם יש בטלפון מספיק משאבים של מעבד אותות תמונה (ISP) כדי להזרים נתונים ממצלמה קדמית וממצלמה אחורית (או ממצלמות אחרות) בו-זמנית, אבל לא בקיבולת מלאה. במקרה כזה, ה-HAL של המצלמה צריך להקצות משאבי חומרה מוגבלים לכל מכשיר מצלמה.

תרחיש לדוגמה

התרחיש הבא מדגים את הבעיה.

בעיה

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

  • מזהה המצלמה 0 הוא מצלמה לוגית שמגובה על ידי מצלמה רחבה ומצלמת Ultrawide, שכל אחת מהן תופסת משאב ISP אחד.
  • מזהה המצלמה 1 הוא מצלמה שמשתמשת במשאב ISP אחד.

למכשיר (טלפון) יש שני ספקי אינטרנט. אם מזהה המצלמה 0 נפתח והוגדרה סשן, יכול להיות ש-HAL של המצלמה ישמור שני ISPs מתוך ציפייה לשימוש במצלמה הרחבה ובמצלמה הרחבה במיוחד.

אם זה המצב, אי אפשר להגדיר אף זרם מהמצלמה הקדמית (מזהה 1) כי שני ספקי האינטרנט נמצאים בשימוש.

פתרון

כדי לפתור את הבעיה הזו, המסגרת יכולה לפתוח את שני מזהי המצלמות 0 ו-1 לפני הגדרת הסשנים, כדי לספק רמז ל-HAL של המצלמה לגבי אופן הקצאת המשאבים (כי עכשיו היא מצפה לפעולה בו-זמנית של המצלמות). עם זאת, זה עלול להוביל ליכולות מוגבלות. לדוגמה, יכול להיות שלא תהיה אפשרות להשתמש במלוא טווח הזום (כי יכול להיות שיהיו בעיות במעבר בין מזהי מצלמות פיזיים).

כדי להטמיע את הפתרון הזה, צריך לבצע את העדכונים הבאים ב-provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds.

  • הגדרת חובה: כדי להפעיל מצלמות בו-זמנית, מסגרת המצלמה צריכה לפתוח את מכשירי המצלמה (@3.2::ICameraDevice::open) לפני הגדרת סשנים במכשירי המצלמה. כך ספקי המצלמות יכולים להקצות משאבים בהתאם.

  • כדי לפתור את הבעיה שקשורה לחוסר יכולת לטפל ביחס טווח הזום המלא, צריך לוודא שאפליקציות של מצלמות, כשמשתמשים במצלמות בו-זמנית, משתמשות בהגדרת הבקרה ZOOM_RATIO רק בין 1x ל-MAX_DIGITAL_ZOOM במקום ב-ZOOM_RATIO_RANGE המלא (כך נמנע מעבר בין מצלמות פיזיות באופן פנימי, שעשוי לדרוש יותר ספקי אינטרנט).

בעיה ב-testDualCameraPreview

כשמבצעים את העדכונים שלמעלה, יכולה להיווצר בעיה בהתנהגות שמותרת בMultiViewTest.java#testDualCameraPreview הבדיקה.

בבדיקה testDualCameraPreview, ההגדרות של הסשנים מתבצעות רק אחרי שפותחים את כל המצלמות. היא פועלת לפי הרצף הבא:

for each camera  in cameraDevices :
  device = openCamera(camera)
     createCaptureSession(device);

עם זאת, הוא מאפשר כשלים בפתיחת המצלמה עם ERROR_MAX_CAMERAS_IN_USE [1]. יכול להיות שאפליקציות של צד שלישי מסתמכות על ההתנהגות הזו.

מכיוון ש-HAL של המצלמה לא ידע את הסט המלא של מזהי המצלמה שנפתחים לפעולה בו-זמנית לפני הגדרת הסשנים, יכול להיות שיהיה לו קשה להקצות משאבי חומרה (בהנחה שיש תחרות על המשאבים האלה).

כדי לפתור את הבעיה הזו, בנוסף לתמיכה בסטרימינג בו-זמני, צריך לשמור על תאימות לאחור. אם מערכות HAL של מצלמות לא יכולות לתמוך בהגדרת סטרימינג מלאה לכל המצלמות שפועלות בו-זמנית, הן צריכות להחזיר שגיאה בקריאות openCamera עם ERROR_MAX_CAMERAS_IN_USE.