Android 14-QPR1 이상을 실행하는 기기의 경우 Android는 기기를 USB 웹캠으로 사용하는 것을 지원합니다. 이 기능을 지원하는 Android 기기는 UVC 기기로 광고되므로 다양한 운영체제 (예: Linux, macOS, Windows, ChromeOS)를 사용하는 다양한 USB 호스트가 기기의 카메라를 웹캠으로 사용할 수 있습니다. DeviceAsWebcam
서비스는 기기를 웹캠으로 사용할 수 있도록 이 기능을 지원합니다.
DeviceAsWebcam 서비스
AOSP의 DeviceAsWebcam
서비스에는 사용자가 장면을 프레임으로 지정할 수 있는 미리보기 활동(DeviceAsWebcamPreview.java
)이 포함되어 있습니다. 미리보기 활동을 통해 사용자는 다음 작업을 할 수 있습니다.
스트리밍이 시작되기 전에 호스트 머신에서 웹캠 피드가 어떻게 표시되는지 미리 봅니다.
호스트로 전송되는 웹캠 피드를 다음과 같이 맞춤설정합니다.
- 스트리밍할 카메라(전면 또는 후면)를 선택합니다.
- 슬라이더 또는 버튼을 사용하여 확대/축소 수준을 선택합니다.
- 미리보기의 특정 영역을 탭하여 영역에 포커스를 맞추거나 포커스를 삭제합니다.
미리보기 활동은 TalkBack, 스위치 제어, 음성 액세스와 같은 Android의 일반 접근성 기능과 함께 작동합니다.
그림 1. 피드를 제어하는 미리보기와 함께 호스트로 스트리밍되는 웹캠 피드
아키텍처
기기를 웹캠으로 사용하는 것을 지원하는 아키텍처는 그림 2에 나와 있습니다. 다음은 DeviceAsWebcam
서비스와 나머지 Android 프레임워크 간의 상호작용 흐름을 설명합니다.
- 사용자가 설정 앱에서 USB 웹캠 옵션을 선택합니다.
- 설정 앱은
UsbManager
클래스를 통해system_server
에 바인더 호출을 전송하여FUNCTION_UVC
가 선택되었음을 알립니다. - 시스템 서버는 다음을 실행합니다.
setUsbFunctions
HAL 인터페이스 호출을 통해 UVC 가젯 함수를 가져오도록 USB 가젯 HAL에 알립니다.- ConfigFs를 사용하여 UVC 가젯 드라이버를 구성하도록 USB 가젯 HAL에 알립니다.
system_server
는 가젯 HAL에서 콜백을 수신하면DeviceAsWebcam
서비스에서 선택할 수 있도록 프레임워크에 브로드캐스트를 전송합니다.- USB 가젯 드라이버는
/dev/video*
에서 V4L2 노드를 통해 호스트로부터 구성 명령어를 수신하면 웹캠 스트림을 시작합니다.
그림 2. DeviceAsWebcam 아키텍처
구현
이 섹션에서는 Android 기기를 웹캠으로 사용하는 방법을 지원하는 방법을 설명합니다.
커널 지원
Android 14 이상에서 일반 커널 이미지 (GKI)는 기본적으로 UVC 가젯 드라이버를 사용 설정합니다 (AOSP 패치의 세부정보 참고).
가젯 HAL에서 UVC 지원
Android 14부터 UVC 기능이 GadgetFunction.aidl
HAL 인터페이스에 포함됩니다. 가젯 HAL의 경우 UVC 가젯은 MTP나 ADB와 같은 다른 ConfigFS 기능과 동일한 방식으로 ConfigFS에 마운트됩니다.
가젯 HAL을 구현하려면 UVC 함수를 ConfigFS에 마운트하도록 수정하세요. 다음은 UVC 기능을 지원하는 가젯 HAL 구현의 예시 스니펫입니다.
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
...
}
...
}
기기가 웹캠으로 작동하는 경우 USB 가젯 HAL이 적절한 VID/PID 조합을 광고하는지 확인합니다.
모든 UVC 로직이 공급업체 init에 있거나 DeviceAsWebcam
서비스에 있으므로 UVC 함수를 ConfigFS에 심볼릭 링크하는 것 외에 UVC 관련 로직은 가젯 HAL에 필요하지 않습니다.
구현에 관한 자세한 내용은 AOSP의 다음 샘플 코드를 참고하세요.
UVC 구성으로 ConfigFS 설정
Android 웹캠에서 지원하는 형식, 크기, 프레임 속도를 UVC 가젯 드라이버에 알리려면 UVC 구성으로 ConfigFS를 설정하세요. 자세한 내용은 ConfigFS UVC 가젯 ABI에 관한 업스트림 Linux 문서를 참고하세요.
다음은 공급업체 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
# ...
이 스니펫은 30fps로 1080p MJPEG 스트림을 공지하도록 UVC 가젯 드라이버를 설정합니다. 이러한 기능은 지원되는 해상도와 프레임 속도를 쿼리할 때 USB 호스트에 전달됩니다.
다음은 웹캠이 광고하는 구성을 선택하는 일반적인 가이드라인입니다.
DeviceAsWebcam
서비스에서 지원하는 두 가지 스트림 형식은 MJPEG와 압축되지 않은 YUYV입니다.- USB 2.0은 480Mbps (60MBps) 데이터 전송을 지원합니다. 즉, 30fps에서는 각 프레임의 최대 크기가 2MB여야 하고 60fps에서는 최대 크기가 1MB여야 합니다.
- 비압축 스트림 (YUYV): 30fps에서 YUYV는 픽셀당 2바이트이므로 지원되는 최대 프레임 크기는 720p입니다.
- 압축된 MJPEG 스트림: YUV에서 1:10 압축 비율을 가정할 때 USB 2.0은 4K (프레임당 1.18MB)를 지원할 수 있습니다.
- 기본 전면 및 후면 카메라 기기는 광고된 모든 프레임 크기를 지원해야 합니다. 이는 사용자가 미리보기 UI를 사용하여 카메라 ID 간에 전환할 수 있기 때문입니다. MJPEG 스트림의 경우 호스트 앱에서 일반적으로 사용하는 크기이므로 공급업체는 480p (640x480), 720p (1280x820), 1080p (1920x1080) 프레임 크기를 광고하는 것이 좋습니다.
- 기본 전면 및 후면 카메라 기기는 광고된 모든 프레임 속도를 지원해야 합니다. 공급업체는 30fps를 지원하는 것이 좋습니다.
웹캠 스트림 구성 (ConfigFS) 추가 예시는 AOSP 샘플 패치를 참고하세요.
빌드에서 웹캠 사용 설정
DeviceAsWebcam
서비스를 사용 설정하려면 device.mk
파일에서 ro.usb.uvc.enabled
시스템 속성을 true
로 설정해야 합니다.
# Enable UVC support
PRODUCT_VENDOR_PROPERTIES += \
ro.usb.uvc.enabled=true
이 시스템 속성이 사용 설정되면 그림 3과 같이 설정 앱의 USB 환경설정 아래에 웹캠 옵션이 표시됩니다. 이 옵션을 선택하면 Android 기기가 호스트 기기에 USB 웹캠으로 표시됩니다.
그림 3. 설정 앱의 USB 환경설정
다음 명령어를 사용하여 ADB를 통해 기기를 USB 웹캠 기능으로 설정할 수도 있습니다.
adb shell svc usb setFunctions uvc
전력 및 열 문제 고려
웹캠 작동은 기기의 카메라가 하루에 여러 시간 동안 켜져 있을 수 있음을 의미하므로 기기의 전력 소비와 열이 특정 한도 미만으로 유지되도록 조치를 취하는 것이 좋습니다. 전력 소비를 한도 미만으로 유지하기 위한 권장 솔루션은 다음과 같습니다.
- 카메라 HAL의 전력 성능을 개선하려면
DeviceAsWebcam
서비스에서STREAM_USE_CASE_VIDEO_CALL
를 사용 설정하세요. STREAM_USE_CASE_VIDEO_CALL
를 사용 설정한 경우에도 전력이 우려되는 경우DeviceAsWebcam
서비스는 실제 스트림을 사용하여 전력 소비를 더욱 줄이는 옵션을 제공합니다. 런타임 리소스 오버레이 (RRO)를 사용하여 사용할 실제 카메라를 지정할 수 있습니다. 물리적 스트림은 동영상 화질을 크게 저하시키고 혼란스러운 UX를 유발하므로 이 솔루션은 최후의 수단으로만 사용하세요.STREAM_USE_CASE_VIDEO_CALL
를 최적화하는 것이 전원 문제를 해결하는 데 가장 좋습니다.DeviceAsWebcam
서비스에서 지원하는 RRO에 관한 자세한 내용은 readme.md를 참고하세요.다음은 논리 카메라 ID 0 대신 실제 카메라 ID 3을 사용하도록 설정된 RRO의 예입니다. AOSP의 예는 DeviceAsWebcamRaven을 참고하세요.
// For logical camera id 0 - use physical camera id 3 {"0": {"3" : "UW"}}
인증
기기에서 DeviceAsWebcam
서비스의 구현을 테스트하려면 다음 테스트를 사용하세요.
- CTS 인증 도구 테스트 웹캠: 형식이 기기에서 지원되는지, 크기가 기기에서 지원되는지, 프레임 속도가 기기에서 지원되는지 테스트합니다.
- 수동 테스트: 다양한 호스트 운영체제에서 다양한 호스트 앱과 함께 웹캠 기능이 작동하는지 테스트합니다.
알려진 문제
다음은 DeviceAsWebcam
서비스의 알려진 문제입니다.
UVC 가젯 드라이버의 스트림이 가끔 깜박이고 손상된 프레임처럼 보이는 것이 표시됩니다. 이 문제는 수정되어 업스트림과 GKI에 병합되었습니다.
Apple의 UVC 드라이버에 버그가 있어 웹캠 모드의 Android 기기는 macOS 호스트에서 USB 3.0 이상 케이블과 호환되지 않습니다.