שימוש במכשיר כמצלמת אינטרנט

במכשירים עם Android מגרסה 14-QPR1 ואילך, אפשר להשתמש במכשיר כמצלמת אינטרנט מסוג USB. מכשירי Android שתומכים בתכונה הזו מפורסמים בתור מכשירי UVC, ומאפשרים למגוון רחב של מארחי USB עם מערכות הפעלה שונות (למשל, Linux,‏ macOS,‏ Windows ו-ChromeOS) להשתמש במצלמה של המכשיר כמצלמת אינטרנט. השירות DeviceAsWebcam תומך בתכונה הזו, שמאפשרת להשתמש במכשיר כמצלמת אינטרנט.

השירות DeviceAsWebcam

השירות DeviceAsWebcam ב-AOSP כולל פעילות תצוגה מקדימה (DeviceAsWebcamPreview.java) שמאפשרת למשתמשים לבחור את הפריים של התמונה. פעילות התצוגה המקדימה מאפשרת למשתמש לבצע את הפעולות הבאות:

  • לפני שמתחילים את הסטרימינג, כדאי לראות איך הפיד של מצלמת האינטרנט ייראה במכונה המארחת.

  • אתם יכולים להתאים אישית את הפיד של מצלמת האינטרנט שנשלח למארח בדרכים הבאות:

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

פעילות התצוגה המקדימה פועלת עם תכונות נגישות כלליות ב-Android, כמו TalkBack, ‏ גישה באמצעות מתג וגישה קולית.

סטרימינג של פיד מצלמת האינטרנט למארח

איור 1. פיד של מצלמת אינטרנט שמשודר למארח עם תצוגה מקדימה של הפיד.

ארכיטקטורה

הארכיטקטורה שתומכת בשימוש במכשיר כמצלמת אינטרנט מופיעה באיור 2. בהמשך מתואר תהליך האינטראקציה של שירות DeviceAsWebcam עם שאר מסגרת Android:

  1. המשתמש בוחר באפשרות של מצלמת ה-USB באפליקציית ההגדרות.
  2. אפליקציית ההגדרות שולחת קריאה ל-binder ל-system_server דרך הכיתה UsbManager, ומעדכנת אותו ש-FUNCTION_UVC נבחר.
  3. שרת המערכת מבצע את הפעולות הבאות:
    1. מודיע ל-HAL של גאדג'ט ה-USB לאחזר את פונקציית הגאדג'ט של UVC באמצעות קריאה לממשק HAL‏ setUsbFunctions.
    2. מודיע ל-HAL של גאדג'ט ה-USB להגדיר את מנהל ההתקן של גאדג'ט ה-UVC באמצעות ConfigFs.
  4. כשמקבלים קריאה חוזרת מ-HAL של הגאדג'ט, system_server שולח שידור ל-framework כדי שהשירות DeviceAsWebcam יזהה אותו.
  5. מנהל ההתקן של גאדג'ט ה-USB מתחיל את הסטרימינג של מצלמת האינטרנט לאחר שהוא מקבל פקודות הגדרה מהמארח דרך צמתים של V4L2 ב-/dev/video*.

ארכיטקטורה של מכשיר כמצלמת אינטרנט

איור 2. הארכיטקטורה של DeviceAsWebcam.

הטמעה

בקטע הזה נסביר איך לתמוך בשימוש במכשיר Android כמצלמת אינטרנט.

תמיכה בליבה

ב-Android מגרסה 14 ואילך, קובץ האימג' של הליבה הגנרית (GKI) מפעיל את הדרייבר של גאדג'ט UVC כברירת מחדל (פרטים נוספים זמינים בתיקון AOSP).

תמיכה ב-UVC ב-HAL של Gadget

החל מגרסה 14 של Android, הפונקציה UVC כלולה בממשק HAL‏ GadgetFunction.aidl. ב-Gadget HAL, ההתקן מסוג UVC מצורף ל-ConfigFS באותו אופן שבו מצורפות פונקציות אחרות של ConfigFS, כמו MTP או ADB.

כדי להטמיע את Gadget HAL, צריך לבצע שינויים כדי לטעון את פונקציית ה-UVC ל-ConfigFS. קטע קוד לדוגמה של הטמעת HAL של Gadget שתומכת בפונקציית UVC:

UsbGadget::setCurrentUsbFunctions(long functions) {
   ...
   // Existing functions
   if ((functions & GadgetFunction::MTP) != 0) {
       ...
       linkFunction("ffs.mtp"); // Mount to ConfigFS
       ...
   }
   ...
   // UVC function follows the same pattern!
   if ((functions & GadgetFunction::UVC) != 0) {
       ...
       linkFunction("uvc.0"); // Mount to ConfigFS
       ...
   }
   ...
}

כשהמכשיר פועל כמצלמת אינטרנט, צריך לוודא ש-HAL של גאדג'ט ה-USB מפרסם את השילובים המתאימים של VID/PID.

מכיוון שכל הלוגיקה של UVC נמצאת ב-init של הספק או בשירות DeviceAsWebcam, אין צורך בלוגיקה ספציפית ל-UVC ב-HAL של הגאדג'ט, מלבד קישור סימלי של פונקציית ה-UVC ל-ConfigFS.

לקבלת הנחיות נוספות להטמעה, אפשר לעיין בדוגמת הקוד הבאה ב-AOSP:

הגדרת ConfigFS עם הגדרות UVC

כדי להודיע למנהל הגאדג'ט של UVC אילו פורמטים, גדלים ושיעורי פריימים נתמכים במצלמת האינטרנט של Android, צריך להגדיר את ConfigFS עם הגדרות UVC. למידע נוסף, קראו את המסמכים של Linux בנושא ConfigFS UVC gadget ABI.

בדוגמה הבאה מוסבר איך ה-vendor init יכול להגדיר את מנהל הגאדג'ט של UVC (קטע קוד ב-AOSP):

# uvc function
   mkdir /configfs_path/functions/uvc.0
   write /configfs_path/functions/uvc.0/function_name "Android Webcam"
   write /configfs_path/functions/uvc.0/streaming_maxpacket 3072
   # setup control params
   mkdir /configfs_path/functions/uvc.0/control/header/h
   symlink /configfs_path/functions/uvc.0/control/header/h \
                /configfs_path/functions/uvc.0/control/class/fs/h
   symlink /configfs_path/functions/uvc.0/control/header/h \
                /configfs_path/functions/uvc.0/control/class/ss/h
   # advertise 1080p resolution for webcam encoded as mjpeg
   mkdir /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p
   write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight 1080
   write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth 1920
   write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize 4147200
   # advertise 30 fps support for 1080p.
   write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval 333333
   write /configfs_path/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval "333333"
   # setup streaming params
   mkdir /configfs_path/functions/uvc.0/streaming/header/h
   symlink /configfs_path/functions/uvc.0/streaming/mjpeg/m \
                /configfs_path/functions/uvc.0/streaming/header/h/m
   symlink /configfs_path/functions/uvc.0/streaming/header/h \
                /configfs_path/functions/uvc.0/streaming/class/fs/h
   symlink /configfs_path/functions/uvc.0/streaming/header/h \
                /configfs_path/functions/uvc.0/streaming/class/hs/h
   symlink /configfs_path/functions/uvc.0/streaming/header/h \
                /config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h
   # ...

קטע הקוד הזה מגדיר את מנהל ההתקן של גאדג'ט ה-UVC כדי לפרסם שידור MJPEG של 1080p בקצב של 30 fps. היכולות האלה מועברות למארח ה-USB כשמתבצעת שאילתה לגבי רזולוציות וקצבי פריימים נתמכים.

אלה ההנחיות הכלליות לבחירת ההגדרות שמוצגות על ידי מצלמת האינטרנט:

  • שני הפורמטים של הסטרימינג שנתמכים בשירות DeviceAsWebcam הם MJPEG ו-YUYV לא דחוס.
  • USB 2.0 תומך בהעברת נתונים במהירות 480 Mbps‏ (60 MBps). כלומר, בקצב של 30 FPS, כל פריים חייב להיות בגודל מקסימלי של 2 MB, ובקצב של 60 FPS, בגודל מקסימלי של 1 MB.
    • שידורים לא דחוסים (YUYV): בקצב של 30 fps, גודל המסגרת המקסימלי שנתמך הוא 720p כי הפורמט YUYV הוא 2 בייטים לכל פיקסל.
    • שידורי MJPEG דחוסים: בהנחה שיחס דחיסה של 1:10 מ-YUV,‏ USB 2.0 יכול לתמוך ב-4K (1.18MB לכל פריים).
  • המצלמה הקדמית והמצלמה האחורית הראשיות חייבות לתמוך בכל גדלי המסגרות שמפורסמים. הסיבה לכך היא שהמשתמש יכול לעבור בין מזהי המצלמות באמצעות ממשק המשתמש של התצוגה המקדימה. לשידורי MJPEG, אנחנו ממליצים לספקים לפרסם גדלי פריימים של 480p‏ (640 x 480), 720p‏ (1,280 x 820) ו-1080p‏ (1,920 x 1,080), כי אלה הגדלים שבהם אפליקציות המארח משתמשות בדרך כלל.
  • המכשירים עם המצלמה הקדמית והאחורית הראשיות חייבים לתמוך בכל קצב הפריימים שפורסמו. מומלץ מאוד לספקים לתמוך ב-30 fps.

דוגמה להוספת הגדרות של סטרימינג ממצלמת אינטרנט (ConfigFS) מופיעה בתיקון לדוגמה ב-AOSP.

הפעלת מצלמת אינטרנט בגרסה היציבה

כדי להפעיל את השירות DeviceAsWebcam, צריך להגדיר את מאפיין המערכת ro.usb.uvc.enabled לערך true בקובץ device.mk.

# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
    ro.usb.uvc.enabled=true

כשמאפיין המערכת הזה מופעל, האפשרות מצלמת אינטרנט מופיעה באפליקציית ההגדרות בקטע 'העדפות USB', כפי שמוצג באיור 3. כשהאפשרות הזו מסומנת, מכשיר Android מופיע כמצלמת אינטרנט מסוג USB במכשיר המארח.

איור 3. העדפות USB באפליקציית ההגדרות.

אפשר גם להגדיר את המכשיר לפעול כמצלמת USB דרך ADB באמצעות הפקודה הבאה:

adb shell svc usb setFunctions uvc

שיקולים לגבי הספק והבעיות התרמו-מכניות

כשמשתמשים במצלמת אינטרנט, המצלמה של המכשיר עשויה לפעול במשך כמה שעות ביום. לכן מומלץ לנקוט פעולות כדי לוודא שצריכת החשמל והטמפרטורה של המכשיר יישארו בגבולות מסוימים. אלה פתרונות מומלצים שיעזרו לכם להימנע מחריגה מהמגבלות של צריכת החשמל:

  • כדי לשפר את ביצועי האנרגיה של HAL המצלמה, מפעילים את STREAM_USE_CASE_VIDEO_CALL בשירות DeviceAsWebcam.
  • אם צריכת החשמל עדיין בעייתית גם כשהאפשרות STREAM_USE_CASE_VIDEO_CALL מופעלת, אפשר להשתמש בשירות DeviceAsWebcam כדי להפחית עוד יותר את צריכת החשמל באמצעות שימוש בזרמים פיזיים. אפשר להשתמש בשכבות-על של משאבים בסביבת זמן הריצה (RRO) כדי לציין באיזו מצלמה פיזית להשתמש. שידור פיזי גורם לירידה משמעותית באיכות הווידאו ולחוויית משתמש מבלבלת, לכן מומלץ להשתמש בפתרון הזה רק כמוצא אחרון. אופטימיזציה של STREAM_USE_CASE_VIDEO_CALL היא הפתרון המועדף לבעיות שקשורות לצריכת חשמל. מידע נוסף על קובצי RRO שנתמכים בשירות DeviceAsWebcam זמין בקובץ readme.md.

    הדוגמה הבאה היא של RRO שהוגדרה להשתמש במזהה המצלמה הפיזי 3 במקום במזהה המצלמה הלוגי 0. דוגמה ב-AOSP מופיעה במאמר DeviceAsWebcamRaven.

    // For logical camera id 0 - use physical camera id 3
    {"0": {"3" : "UW"}}
    

אימות

כדי לבדוק את ההטמעה של שירות DeviceAsWebcam במכשיר, אפשר להשתמש בבדיקות הבאות:

  • בדיקת המאמת של CTS webcam: בדיקה אם המכשיר תומך בפורמטים, בגדלים ובקצב הפריימים.
  • בדיקות ידניות: בדיקה שהתכונה של מצלמת האינטרנט פועלת עם מגוון אפליקציות מארחות במגוון מערכות הפעלה מארחות.

בעיות מוכרות

הבעיות הבאות ידועות בשירות DeviceAsWebcam: