기기를 웹캠으로 사용

Android 14-QPR1 이상을 실행하는 기기의 경우 Android는 기기를 USB 웹캠으로 사용하는 것을 지원합니다. 이 기능을 지원하는 Android 기기는 UVC 기기로 광고되며, 이를 통해 다양한 운영체제 (예: Linux, macOS, Windows, ChromeOS)를 사용하는 다양한 USB 호스트가 기기의 카메라를 웹캠으로 사용할 수 있습니다. DeviceAsWebcam 서비스는 기기를 웹캠으로 사용하기 위한 이 기능을 지원합니다.

DeviceAsWebcam 서비스

AOSP의 DeviceAsWebcam 서비스에는 사용자가 장면을 프레이밍할 수 있는 미리보기 활동(DeviceAsWebcamPreview.java)이 포함되어 있습니다. 미리보기 활동을 사용하면 사용자가 다음 작업을 할 수 있습니다.

  • 스트리밍을 시작하기 전에 호스트 머신에서 웹캠 피드가 어떻게 표시되는지 미리 봅니다.

  • 다음과 같은 방법으로 호스트로 전송되는 웹캠 피드를 맞춤설정합니다.

    • 전면 또는 후면 중 스트리밍할 카메라를 선택합니다.
    • 슬라이더 또는 버튼을 사용하여 확대/축소 수준을 선택합니다.
    • 미리보기의 특정 영역을 탭하여 영역에 포커스를 맞추거나 포커스를 삭제합니다.

미리보기 활동은 TalkBack, 스위치 제어, 음성 액세스와 같은 Android의 일반적인 접근성 기능과 함께 작동합니다.

호스트로 스트리밍된 웹캠 피드

그림 1. 미리보기로 피드를 제어하는 호스트에 스트리밍되는 웹캠 피드

아키텍처

기기를 웹캠으로 사용하는 것을 지원하는 아키텍처는 그림 2와 같습니다. 다음은 DeviceAsWebcam 서비스와 나머지 Android 프레임워크 간의 상호작용 흐름을 설명합니다.

  1. 사용자가 설정 앱에서 USB 웹캠 옵션을 선택합니다.
  2. 설정 앱은 UsbManager 클래스를 통해 system_server에 바인더 호출을 전송하여 FUNCTION_UVC이 선택되었음을 알립니다.
  3. 시스템 서버는 다음을 실행합니다.
    1. USB 가젯 HAL에 setUsbFunctions HAL 인터페이스 호출을 통해 UVC 가젯 함수를 가져오라고 알립니다.
    2. USB 가젯 HAL에 ConfigFs를 사용하여 UVC 가젯 드라이버를 구성하도록 알립니다.
  4. 가젯 HAL에서 콜백을 수신하면 system_serverDeviceAsWebcam 서비스에서 선택할 브로드캐스트를 프레임워크로 전송합니다.
  5. USB 가젯 드라이버는 /dev/video*의 V4L2 노드를 통해 호스트로부터 구성 명령어를 수신하면 웹캠 스트림을 시작합니다.

기기를 웹캠으로 사용하기 위한 아키텍처

그림 2. DeviceAsWebcam 아키텍처

구현

이 섹션에서는 Android 기기를 웹캠으로 사용하는 것을 지원하는 방법을 설명합니다.

커널 지원

Android 14 이상에서는 일반 커널 이미지 (GKI)가 기본적으로 UVC 가젯 드라이버를 사용 설정합니다 (AOSP 패치에서 세부정보 참고).

가젯 HAL에서 UVC 지원

Android 14부터 UVC 함수가 GadgetFunction.aidl HAL 인터페이스에 포함됩니다. Gadget HAL의 경우 UVC 가젯은 MTP나 ADB와 같은 다른 ConfigFS 함수와 동일한 방식으로 ConfigFS에 마운트됩니다.

Gadget HAL을 구현하려면 UVC 함수를 ConfigFS에 마운트하도록 수정합니다. 다음은 UVC 함수를 지원하는 Gadget 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 서비스에 있으므로 Gadget HAL에는 UVC 함수를 ConfigFS에 심볼릭 링크하는 것 외에는 UVC 관련 로직이 필요하지 않습니다.

구현에 관한 자세한 안내는 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 호스트가 지원되는 해상도와 프레임 속도를 쿼리할 때 USB 호스트에 전달됩니다.

다음은 웹캠이 광고하는 구성을 선택하기 위한 일반적인 가이드라인입니다.

  • DeviceAsWebcam 서비스에서 지원하는 두 가지 스트림 형식은 MJPEG 및 비압축 YUYV입니다.
  • USB 2.0은 480 Mbps (60 MBps)의 데이터 전송을 지원합니다. 즉, 30fps의 경우 각 프레임의 최대 크기는 2MB여야 하며, 60fps의 경우 최대 크기는 1MB여야 합니다.
    • 비압축 스트림 (YUYV): YUYV는 픽셀당 2바이트이므로 30fps의 경우 지원되는 최대 프레임 크기는 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 서비스의 알려진 문제입니다.