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

מערכת 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, שכולל את השיטות הבאות:

למידע על הטמעה לדוגמה של ממשק HAL‏ ICameraProvider@2.6, אפשר לעיין בספריית 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.