Đối với các thiết bị chạy Android 14-QPR1 trở lên, Android hỗ trợ sử dụng
thiết bị làm webcam USB. Các thiết bị Android hỗ trợ tính năng này đang quảng cáo
dưới dạng thiết bị UUV, cho phép nhiều máy chủ USB với các chế độ cài đặt khác nhau
hệ điều hành (ví dụ: Linux, macOS, Windows và ChromeOS) sử dụng
máy ảnh 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 lấy khung hình cho cảnh. Bản xem trước
Hoạt động cho phép người dùng thực hiện các 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 phát trực tiếp bắt đầu.
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 của một khu vực.
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ư dưới dạng TalkBack, Tiếp cận bằng công tắc và Điều khiển bằng giọng nói.
Hình 1. Nguồn cấp dữ liệu webcam đang được phát trực tiếp đến người tổ chức với bản xem trước đang điều khiển nguồn cấp dữ liệu.
Kiến trúc
Kiến trúc hỗ trợ sử dụng thiết bị làm webcam được minh hoạ trong
Hình 2. Phần sau đây mô tả quy trình tương tác của DeviceAsWebcam
với phần còn lại của khung Android:
- Người dùng chọn tuỳ chọn webcam USB trong ứng dụng Cài đặt.
- Ứng dụng Cài đặt gửi lệnh gọi liên kết đến
system_server
thông qua LớpUsbManager
cho biết 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 tiện ích USB để truy xuất chức năng tiện ích UVC thông qua
Lệnh gọi giao diện HAL
setUsbFunctions
. - 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.
- Thông báo cho HAL tiện ích USB để truy xuất chức năng tiện ích UVC thông qua
Lệnh gọi giao diện HAL
- Khi nhận được cuộc gọi lại từ HAL tiện ích,
system_server
sẽ gửi truyền tin lên khung do dịch vụDeviceAsWebcam
tiếp nhận. - Trình điều khiển tiện ích USB sẽ khởi động luồng webcam khi nhận được cấu hình
các lệnh từ máy chủ lưu trữ 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ợ 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) bật tiện ích UVC trình điều khiển theo mặc định (xem thông tin chi tiết trong bản vá AOSP.
Hỗ trợ UVC trong HAL tiện ích
Kể từ Android 14, hàm UVC có trong
GadgetFunction.aidl
Giao diện HAL. Đối với HAL Tiện ích, UVC
được gắn kết 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 của tiện ích, hãy sửa đổi để gắn chức năng UVC thành ConfigFS. Sau đây là một đoạn mã mẫu về 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 tiện ích USB đang quảng cáo các tổ hợp VID/PID thích hợp.
Bởi vì tất cả logic UVC đều nằm trong lệnh init của nhà cung cấp hoặc trong DeviceAsWebcam
dịch vụ, không có logic cụ thể UVC, ngoài việc liên kết tượng trưng cho hàm UVC tới
ConfigFS, 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ề đị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 với cấu hình UVC. Cho để biết thêm thông tin, hãy xem tài liệu Linux về phiên bản ngược dòng (upstream) trên ConfigFS UVC ABI tiện ích.
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 cài đặt trình điều khiển tiện ích UVC để quảng cáo luồng MJPEG 1080p tại 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 độ phân giải và tốc độ khung hình được hỗ trợ.
Sau đây là các nguyên tắc chung để chọn cấu hình 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). Chiến dịch 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, khung hình tối đa được hỗ trợ kích thước là 720p vì YUYV là 2 byte trên mỗi pixel.
- Luồng MJPEG được nén: Giả sử tỷ lệ nén 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ị có máy ảnh chính trước và sau phải hỗ trợ tất cả kích thước khung hình mà đều đượ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ã máy ảnh bằng cách sử dụng giao diện người dùng để xem trước. Đối với các luồng MJPEG, nhà cung cấp nên quảng cáo độ phân giải 480p (640 x 480), 720p (1280 x 820) và 1080p (1920 x 1080) vì đây là các kích thước thường được ứng dụng lưu trữ sử dụng.
- Các thiết bị có 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.
Để xem 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 ro.usb.uvc.enabled
thuộc tính hệ thống vào 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, một tùy chọn Webcam sẽ xuất hiện trong Ứng dụng Settings (Cài đặt) trong phần lựa chọn ưu tiên USB như trong Hình 3. Khi lựa chọn là đã chọn, thiết bị Android sẽ xuất hiện dưới dạng webcam USB trước 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 cách sử dụng :
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ể được bật cho nhiều giờ mỗi ngày, do đó chúng tôi khuyên bạn nên tiến hành các biện pháp để đảm bảo nguồn điện mức tiêu thụ và nhiệt của thiết bị vẫn trong một số giới hạn nhất định. Chiến lược phát hành đĩa đơn 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 nhờ 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
, Dịch vụDeviceAsWebcam
cung cấp lựa chọn giảm pin hơn nữa mức tiêu thụ bằng cách sử dụng luồng vật lý. Bạn có thể sử dụng lớp phủ tài nguyên thời gian chạy (RRO) để chỉ định máy ảnh thực nào sử dụng. Sự kiện phát trực tiếp thực tế làm giảm đáng kể chất lượng video và dẫn đến gây nhầm lẫn cho trải nghiệm người dùng, vì vậy, bạn chỉ nên sử dụng giải pháp này nếu không còn cách nào khác. Đang tối ưu hoáSTREAM_USE_CASE_VIDEO_CALL
là giải pháp ưu tiên để tăng năng lượng các mối quan ngại của mình. Để biết thêm thông tin về RRO mà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 thực 3 thay vì mã nhận dạng máy ảnh logic 0. Để biết 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ị của bạn, hãy sử dụng
các phép kiểm thử sau:
- Kiểm tra dành cho webcam của nhà xác minh CTS: Kiểm tra để đảm bảo định dạng, kích thước và tốc độ khung hình được thiết bị hỗ trợ.
- Kiểm thử thủ công: Kiểm tra để đả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ủ.
Vấn đề đã biết
Sau đây là các vấn đề đã biết đối với dịch vụ DeviceAsWebcam
:
Luồng của trình điều khiển tiện ích UVC đôi khi nhấp nháy và cho thấy các khung hình bị hỏng. Vấn đề này đã được khắc phục và hợp nhất ở thượng nguồn và trong GKI.
Các thiết bị Android ở chế độ webcam không thể bật cáp USB 3.0 trở lên macOS lưu trữ do gặp lỗi với trình điều khiển UVC của Apple.