Đố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 sẽ quảng cáo là thiết bị UVC, cho phép nhiều máy chủ USB có các hệ điều hành khác nhau (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 một hoạt động xem trước (DeviceAsWebcamPreview.java
) cho phép người dùng tạo khung 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 từ webcam trên máy chủ lưu trữ trước khi bắt đầu phát trực tiếp.
Tuỳ chỉnh nguồn cấp dữ liệu từ webcam được gửi đến người tổ chức theo những cách sau:
- Chọn camera để phát trực tiếp, camera trước hoặc sau.
- Chọn mức thu phóng bằng thanh trượt hoặc nút.
- Nhấn vào một vùng cụ thể trong 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 này hoạt động với các tính năng hỗ trợ tiếp cận chung trên Android, chẳng hạn như TalkBack, Tiếp cận bằng công tắc và Truy cập bằng giọng nói.
Hình 1. Nguồn cấp dữ liệu từ webcam đang được truyền phát đến một người tổ chức có quyền kiểm soát nguồn cấp dữ liệu thông qua chế độ xem trước.
Kiến trúc
Hình 2 minh hoạ cấu trúc hỗ trợ việc sử dụng thiết bị làm webcam. 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:
- Người dùng chọn chế độ webcam USB trong ứng dụng Cài đặt.
- Ứ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ớpUsbManager
, thông báo cho lớp này rằngFUNCTION_UVC
đã được chọn. - Máy chủ hệ thống sẽ thực hiện những việc sau:
- Thông báo cho HAL của thiết bị USB để truy xuất chức năng của thiết bị UVC thông qua lệnh gọi giao diện HAL
setUsbFunctions
. - Thông báo cho HAL của thiết bị USB để định cấu hình trình điều khiển thiết bị UVC bằng ConfigFs.
- Thông báo cho HAL của thiết bị USB để truy xuất chức năng của thiết bị UVC thông qua lệnh gọi giao diện HAL
- Khi nhận được lệnh gọi lại từ HAL của thiết bị,
system_server
sẽ gửi một thông báo đến khung để được dịch vụDeviceAsWebcam
chọn. - Trình điều khiển thiết bị USB sẽ bắt đầu truyền phát trực tiếp từ webcam khi nhận được các lệnh định cấu hình từ máy chủ thông qua các nút V4L2 tại
/dev/video*
.
Hình 2. Cấu trúc DeviceAsWebcam.
Triển khai
Phần này mô tả cách hỗ trợ việc sử dụng thiết bị Android làm webcam.
Hỗ trợ kernel
Đối với Android 14 trở lên, Hình ảnh hạt nhân chung (GKI) sẽ bật trình điều khiển thiết bị UVC theo mặc định (xem thông tin chi tiết trong bản vá AOSP).
Hỗ trợ UVC trong HAL của thiết bị
Kể từ Android 14, chức năng UVC sẽ có trong giao diện HAL GadgetFunction.aidl
. Đối với Gadget HAL, thiết bị UVC được gắn vào ConfigFS theo cách tương tự như các chức năng ConfigFS khác, chẳng hạn như MTP hoặc ADB.
Để triển khai Gadget HAL, hãy sửa đổi để gắn chức năng UVC vào ConfigFS. Sau đây là một đoạn mã ví dụ về việc triển khai Gadget HAL hỗ trợ chức năng 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 thiết bị USB đang quảng cáo các tổ hợp VID/PID phù hợp.
Vì mọi logic UVC đều nằm trong quá trình khởi động của nhà cung cấp hoặc trong dịch vụ DeviceAsWebcam
, nên không cần logic cụ thể nào của UVC, ngoài việc liên kết tượng trưng hàm UVC với ConfigFS trong HAL của Thiết bị.
Để được hướng dẫn thêm về cách triển khai, hãy xem mã mẫu sau đây 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 thiết bị UVC biết những định dạng, kích thước và tốc độ khung hình được webcam Android hỗ trợ, hãy thiết lập ConfigFS bằng các cấu hình UVC. Để biết thêm thông tin, hãy xem tài liệu Linux nguồn mở về ABI của thiết bị ConfigFS UVC.
Sau đây là ví dụ về cách vendor init có thể thiết lập trình điều khiển thiết bị 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 thiết bị UVC để quảng cáo luồng MJPEG 1080p ở tốc độ 30 khung hình/giây. Những khả năng này được truyền đến máy chủ USB khi máy chủ truy vấn độ phân giải và tốc độ khung hình được hỗ trợ.
Sau đây là hướng dẫn chung để chọn cấu hình mà webcam quảng cáo:
- Dịch vụ
DeviceAsWebcam
hỗ trợ 2 định dạng luồng là MJPEG và YUYV không nén. - USB 2.0 hỗ trợ tốc độ truyền dữ liệu 480 Mbps (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 cho mỗi pixel.
- Luồng MJPEG nén: Giả sử tỷ lệ nén là 1:10 từ YUV, USB 2.0 có thể hỗ trợ 4K (1,18 MB mỗi khung hình).
- Các thiết bị camera trước và sau chính phải hỗ trợ tất cả các kích thước khung hình được quảng cáo. Lý do là vì người dùng có thể chuyển đổi giữa các mã nhận dạng camera bằng giao diện người dùng xem trước. Đối với luồng MJPEG, 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 các ứng dụng lưu trữ sử dụng.
- Thiết bị camera trước và sau chính 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.
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 bạn bật thuộc tính hệ thống này, lựa chọn Webcam (Webcam) sẽ xuất hiện trong ứng dụng Cài đặt ở phần Lựa chọn ưu tiên về USB như minh hoạ trong Hình 3. Khi bạn chọn chế độ này, thiết bị Android sẽ xuất hiện dưới dạng một webcam USB đối với thiết bị chủ.
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ị ở chế độ 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 các vấn đề về nguồn điện và nhiệt
Hoạt động của webcam có nghĩa là camera của thiết bị có thể 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 và nhiệt của thiết bị vẫn nằm trong giới hạn nhất định. Sau đây là các giải pháp được đề xuất để giữ mức tiêu thụ điện năng dưới hạn mức:
- Để có hiệu suất nguồn tốt hơn từ HAL camera, hãy bật
STREAM_USE_CASE_VIDEO_CALL
trong dịch vụDeviceAsWebcam
. Nếu bạn lo ngại về mức tiêu thụ điện ngay cả khi đã bật
STREAM_USE_CASE_VIDEO_CALL
, thì dịch vụDeviceAsWebcam
sẽ cung cấp một lựa chọn để giảm mức tiêu thụ điện hơn nữa bằng cách sử dụng các luồng dữ liệu thực. Bạn có thể sử dụng lớp phủ tài nguyên thời gian chạy (RRO) để chỉ định camera thực cần sử dụng. Luồng vật lý 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, bạn chỉ nên sử dụng giải pháp này khi không còn cách nào khác. Tối ưu hoáSTREAM_USE_CASE_VIDEO_CALL
là giải pháp ưu tiên cho các vấn đề về nguồn điện. Để biết thêm thông tin về các 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ã nhận dạng camera thực 3 thay vì mã nhận dạng camera logic 0. Để xem ví dụ trong AOSP, 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ị, hãy sử dụng các kiểm thử sau:
- Trình xác minh CTS webcam: Kiểm thử để đảm bảo 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 lưu trữ.
Vấn đề đã biết
Sau đây là các vấn đề đã biết đối với dịch vụ DeviceAsWebcam
:
Đôi khi, luồng của trình điều khiển thiết bị UVC nhấp nháy và cho thấy những khung hình có vẻ như bị hỏng. Vấn đề này đã được khắc phục và hợp nhất ở nguồn trên và trong GKI.
Các bản sửa lỗi ngược dòng:
Các thiết bị Android ở chế độ webcam không hoạt động với cáp USB 3.0 trở lên trên máy chủ macOS do trình điều khiển UVC của Apple gặp lỗi.