Dùng thiết bị làm webcam

Đối với các thiết bị chạy Android 14-QPR1 trở lên, Android hỗ trợ việc sử dụng thiết bị làm webcam USB. Các thiết bị Android hỗ trợ tính năng này được quảng cáo là một thiết bị UUV (UVC), cho phép nhiều máy chủ USB có nhiều hệ điều hành (ví dụ: Linux, macOS, Windows và ChromeOS) sử dụng camera của thiết bị làm webcam. Dịch vụ DeviceAsWebcam hỗ trợ tính năng này để dùng thiết bị làm webcam.

Dịch vụ DeviceAsWebcam

Dịch vụ DeviceAsWebcam trong AOSP bao gồm hoạt động xem trước (DeviceAsWebcamPreview.java) cho phép người dùng lấy khung hình cho cảnh. Hoạt động xem trước cho phép người dùng làm những việc sau:

  • Xem trước giao diện của nguồn cấp dữ liệu webcam trên máy chủ trước khi bắt đầu phát trực tiếp.

  • Tuỳ chỉnh nguồn cấp dữ liệu webcam được gửi đến máy chủ theo các cách sau:

    • Chọn camera để phát trực tiếp, trước hoặc sau.
    • Chọn mức thu phóng bằng thanh trượt hoặc các nút.
    • Nhấn vào một vùng cụ thể của bản xem trước để lấy nét hoặc xoá tiêu điểm trên một vùng.

Hoạt động xem trước hoạt động với bộ tính năng hỗ trợ tiếp cận chung trên Android như TalkBack, Tiếp cận bằng công tắcĐiều khiển bằng giọng nói.

nguồn cấp dữ liệu webcam được truyền trực tuyến đến máy chủ

Hình 1. Nguồn cấp dữ liệu webcam đang được phát trực tuyến đến máy chủ lưu trữ có bản xem trước sẽ kiểm soát nguồn cấp dữ liệu.

Cấu trúc

Kiến trúc hỗ trợ dùng thiết bị làm webcam được minh hoạ trong Hình 2. Nội dung sau đây mô tả quy trình tương tác của dịch vụ DeviceAsWebcam với phần còn lại của khung Android:

  1. Người dùng chọn tuỳ chọn webcam USB trong ứng dụng Cài đặt.
  2. Ứng dụng Cài đặt gửi một lệnh gọi liên kết đến system_server thông qua lớp UsbManager để cho biết rằng FUNCTION_UVC đã được chọn.
  3. Máy chủ hệ thống sẽ thực hiện những việc sau:
    1. Thông báo cho HAL của tiện ích USB để truy xuất chức năng của tiện ích UVC thông qua lệnh gọi giao diện HAL setUsbFunctions.
    2. Thông báo cho HAL tiện ích USB định cấu hình trình điều khiển tiện ích UVC bằng cách sử dụng ConfigF.
  4. Khi nhận được lệnh gọi lại từ HAL của tiện ích, system_server sẽ gửi một thông báo đến khung để dịch vụ DeviceAsWebcam tiếp nhận.
  5. Trình điều khiển tiện ích USB sẽ khởi động luồng webcam khi nhận được các lệnh cấu hình từ máy chủ thông qua các nút V4L2 tại /dev/video*.

thiết bị là cấu trúc webcam

Hình 2. Cấu trúc DeviceAsWebcam.

Triển khai

Phần này mô tả cách hỗ trợ sử dụng thiết bị Android làm webcam.

Hỗ trợ kernel

Đối với Android 14 trở lên, theo mặc định, Hình ảnh hạt nhân chung (GKI) sẽ bật trình điều khiển tiện ích UVC (xem thông tin chi tiết trong bản vá AOSP).

Hỗ trợ UVC trong HAL tiện ích

Kể từ Android 14, chức năng UVC sẽ có trong giao diện HAL GadgetFunction.aidl. Đối với HAL tiện ích, tiện ích UVC được gắn vào ConfigFS theo cách tương tự như các hàm ConfigFS khác như MTP hoặc ADB.

Để triển khai HAL tiện ích, hãy sửa đổi để gắn hàm UVC vào ConfigFS. Sau đây là một đoạn mã ví dụ về cách triển khai HAL Tiện ích hỗ trợ hàm 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
       ...
   }
   ...
}

Khi thiết bị hoạt động như một webcam, hãy đảm bảo HAL của tiện ích USB hiển thị các tổ hợp VID/PID thích hợp.

Vì tất cả logic UVC đều nằm trong khởi tạo của nhà cung cấp hoặc trong dịch vụ DeviceAsWebcam, nên không có logic dành riêng cho UVC (ngoài việc liên kết tượng trưng của hàm UVC với ConfigFS) là bắt buộc trong HAL tiện ích.

Để được hướng dẫn thêm về cách triển khai, hãy xem mã mẫu sau trong AOSP:

Thiết lập ConfigFS bằng cấu hình UVC

Để thông báo cho trình điều khiển tiện ích UVC về các định dạng, kích thước và tốc độ khung hình mà webcam Android hỗ trợ, hãy thiết lập ConfigFS với cấu hình UVC. Để biết thêm thông tin, hãy xem tài liệu về Linux ngược dòng trên ABI tiện ích ConfigFS UVC.

Sau đây là ví dụ về cách khởi tạo nhà cung cấp có thể thiết lập trình điều khiển tiện ích UVC (đoạn mã trong 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
   # ...

Đoạn mã này thiết lập trình điều khiển tiện ích UVC để quảng cáo luồng MJPEG 1080p ở tốc độ 30 khung hình/giây. Các chức năng này sẽ được thông báo đến máy chủ USB khi truy vấn các độ phân giải và tốc độ khung hình được hỗ trợ.

Sau đây là các nguyên tắc chung về cách chọn cấu hình mà webcam quảng cáo:

  • Hai định dạng luồng được dịch vụ DeviceAsWebcam hỗ trợ là MJPEG và YUYV không nén.
  • USB 2.0 hỗ trợ chuyển dữ liệu với tốc độ 480 Mb/giây (60 MB/giây). Điều này có nghĩa là ở tốc độ 30 khung hình/giây, mỗi khung hình phải có kích thước tối đa là 2 MB; và ở tốc độ 60 khung hình/giây, kích thước tối đa là 1 MB.
    • Luồng không nén (YUYV): Ở tốc độ 30 khung hình/giây, kích thước khung hình tối đa được hỗ trợ là 720p vì YUYV là 2 byte/pixel.
    • Luồng MJPEG được nén: Với tỷ lệ nén 1:10 của YUV, USB 2.0 có thể hỗ trợ chất lượng 4K (1,18 MB trên mỗi khung hình).
  • Các thiết bị camera chính trước và sau phải hỗ trợ tất cả các kích thước khung hình được quảng cáo. Điều này là do người dùng có thể chuyển đổi giữa các mã nhận dạng máy ảnh bằng giao diện người dùng xem trước. Đối với luồng MJPEG, các nhà cung cấp nên quảng cáo kích thước khung hình 480p (640 x 480), 720p (1280 x 820) và 1080p (1920 x 1080) vì đây là những kích thước thường được ứng dụng lưu trữ sử dụng.
  • Các thiết bị máy ảnh chính trước và sau phải hỗ trợ tất cả tốc độ khung hình được quảng cáo. Nhà cung cấp nên hỗ trợ tốc độ 30 khung hình/giây.

Để biết ví dụ về cách thêm cấu hình luồng webcam (ConfigFS), hãy xem bản vá mẫu AOSP (Dự án nguồn mở Android).

Bật webcam trong bản dựng

Để bật dịch vụ DeviceAsWebcam, bạn phải đặt thuộc tính hệ thống ro.usb.uvc.enabled thành true trong tệp device.mk.

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

Khi thuộc tính hệ thống này được bật, tuỳ chọn Webcam sẽ xuất hiện trong ứng dụng Cài đặt trong phần lựa chọn ưu tiên USB như minh hoạ trong Hình 3. Khi bạn chọn tuỳ chọn này, thiết bị Android sẽ xuất hiện dưới dạng webcam USB kết nối với thiết bị lưu trữ.

Hình 3. Lựa chọn ưu tiên về USB trong ứng dụng Cài đặt.

Bạn cũng có thể đặt thiết bị thành chức năng webcam USB thông qua ADB bằng lệnh sau:

adb shell svc usb setFunctions uvc

Cân nhắc vấn đề về điện và nhiệt

Hoạt động webcam có nghĩa là camera của thiết bị có thể ở trạng thái bật trong nhiều giờ mỗi ngày. Vì vậy, bạn nên thực hiện các biện pháp để đảm bảo mức tiêu thụ điện năng và nhiệt của thiết bị vẫn ở một số giới hạn nhất định. Sau đây là các giải pháp được đề xuất để duy trì mức tiêu thụ điện năng ở mức giới hạn:

  • Để tăng hiệu suất năng lượng từ lớp trừu tượng phần cứng (HAL) của máy ảnh, hãy bật STREAM_USE_CASE_VIDEO_CALL trong dịch vụ DeviceAsWebcam.
  • Nếu bạn lo ngại về nguồn điện ngay cả khi bật STREAM_USE_CASE_VIDEO_CALL, thì dịch vụ DeviceAsWebcam sẽ cung cấp một tuỳ chọn để giảm mức tiêu thụ điện năng hơn nữa bằng cách sử dụng luồng thực. Bạn có thể sử dụng lớp phủ tài nguyên trong thời gian chạy (RRO) để chỉ định máy ảnh thực nào sẽ sử dụng. Luồng thực tế làm giảm đáng kể chất lượng video và dẫn đến trải nghiệm người dùng khó hiểu, vì vậy, chỉ nên sử dụng giải pháp này làm phương án cuối cùng. Tối ưu hoá STREAM_USE_CASE_VIDEO_CALL là giải pháp được ưu tiên để xử lý các mối lo ngại. Để biết thêm thông tin về RRO mà dịch vụ DeviceAsWebcam hỗ trợ, hãy xem readme.md.

    Sau đây là ví dụ về một RRO được thiết lập để sử dụng mã máy ảnh vật lý 3 thay vì mã máy ảnh logic 0. Để xem ví dụ trong AOSP (Dự án nguồn mở Android), hãy xem DeviceAsWebcamRaven.

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

Xác minh

Để kiểm thử việc triển khai dịch vụ DeviceAsWebcam trên thiết bị của bạn, hãy sử dụng các kiểm thử sau:

  • Kiểm tra webcam của nhà xác minh CTS: Kiểm tra để chắc chắn rằng thiết bị hỗ trợ các định dạng, kích thước và tốc độ khung hình.
  • Kiểm thử thủ công: Kiểm thử để đảm bảo tính năng webcam hoạt động với nhiều ứng dụng lưu trữ trên nhiều hệ điều hành của máy chủ lưu trữ.

Vấn đề đã biết

Sau đây là các vấn đề đã biết đối với dịch vụ DeviceAsWebcam: