기기를 웹캠으로 사용

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

DeviceAsWebcam 서비스

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

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

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

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

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

호스트로 스트리밍되는 웹캠 피드

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

아키텍처

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

  1. 사용자가 설정 앱에서 USB 웹캠 옵션을 선택합니다.
  2. 설정 앱은 UsbManager 클래스를 통해 system_server에 바인더 호출을 보내 FUNCTION_UVC가 선택되었음을 알립니다.
  3. 시스템 서버는 다음을 실행합니다.
    1. setUsbFunctions HAL 인터페이스 호출을 통해 UVC 가젯 함수를 검색하도록 USB 가젯 HAL에 알립니다.
    2. ConfigF를 사용하여 UVC 가젯 드라이버를 구성하도록 USB 가젯 HAL에 알립니다.
  4. 가젯 HAL에서 콜백을 수신하면 system_server는 프레임워크에 브로드캐스트를 전송하여 DeviceAsWebcam 서비스에서 선택할 수 있도록 합니다.
  5. 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 서비스에 있으므로 가젯 HAL에는 UVC 함수를 ConfigFS에 심볼릭으로 연결하는 것 외에는 UVC 관련 로직이 필요하지 않습니다.

구현에 관한 추가 안내는 AOSP의 다음 샘플 코드를 참고하세요.

UVC 구성으로 ConfigFS 설정

Android 웹캠에서 지원하는 형식, 크기, 프레임 속도를 UVC 가젯 드라이버에 알리려면 UVC 구성으로 ConfigFS를 설정합니다. 자세한 내용은 ConfigFS UVC 가젯 ABI에 관한 업스트림 Linux 문서를 참고하세요.

다음은 공급업체 초기화에서 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
   # ...

이 스니펫은 UVC 가젯 드라이버를 설정하여 30fps로 1080p MJPEG 스트림을 광고합니다. 이러한 기능은 지원되는 해상도 및 프레임 속도를 쿼리할 때 USB 호스트에 전달됩니다.

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

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