카메라

Android 카메라 HAL 아이콘

Android의 카메라 하드웨어 추상화 계층(HAL)은 카메라 2 의 상위 수준 카메라 프레임워크 API를 기본 카메라 드라이버 및 하드웨어에 연결합니다. 카메라 하위 시스템에는 카메라 파이프라인 구성 요소에 대한 구현이 포함되어 있는 반면 카메라 HAL은 이러한 구성 요소 버전을 구현하는 데 사용할 인터페이스를 제공합니다.

건축물

다음 그림과 목록은 HAL 구성요소를 설명합니다.

안드로이드 카메라 아키텍처

그림 1. 카메라 아키텍처

앱 프레임워크
앱 프레임워크 수준에는 카메라 2 API를 사용하여 카메라 하드웨어와 상호 작용하는 앱의 코드가 있습니다. 내부적으로 이 코드는 해당 바인더 인터페이스를 호출하여 카메라와 상호 작용하는 기본 코드에 액세스합니다.
에이즈
CameraService 와 연결된 바인더 인터페이스는 frameworks/av/camera/aidl/android/hardware 에서 찾을 수 있습니다. 생성된 코드는 물리적 카메라에 대한 액세스 권한을 얻기 위해 하위 수준의 기본 코드를 호출하고 CameraDevice 를 생성하는 데 사용되는 데이터를 반환하고 결국 프레임워크 수준에서 CameraCaptureSession 개체를 반환합니다.
기본 프레임워크
frameworks/av/ 에 있는 이 프레임워크는 CameraDeviceCameraCaptureSession 클래스와 동일한 기본 기능을 제공합니다. NDK 카메라2 참조도 참조 하십시오.
바인더 IPC 인터페이스
IPC 바인더 인터페이스는 프로세스 경계를 ​​넘어 통신을 용이하게 합니다. frameworks/av/camera/camera/aidl/android/hardware 디렉토리에 카메라 서비스를 호출하는 여러 카메라 바인더 클래스가 있습니다. ICameraService 는 카메라 서비스에 대한 인터페이스입니다. ICameraDeviceUser 는 열려 있는 특정 카메라 장치에 대한 인터페이스입니다. ICameraServiceListenerICameraDeviceCallbacks 는 애플리케이션 프레임워크에 대한 각각의 CameraServiceCameraDevice 콜백입니다.
카메라 서비스
frameworks/av/services/camera/libcameraservice/CameraService.cpp 에 있는 카메라 서비스는 HAL과 상호작용하는 실제 코드입니다.
하드웨어 추상화 계층은 카메라 서비스가 호출하고 카메라 하드웨어가 올바르게 작동하도록 구현해야 하는 표준 인터페이스를 정의합니다.

HAL 구현

HAL은 카메라 드라이버와 상위 수준 Android 프레임워크 사이에 있으며 앱이 카메라 하드웨어를 올바르게 작동할 수 있도록 구현해야 하는 인터페이스를 정의합니다. 카메라 HAL의 HIDL 인터페이스는 hardware/interfaces/camera 에 정의되어 있습니다.

일반적인 바인더화된 HAL은 다음 HIDL 인터페이스를 구현해야 합니다.

참조 HIDL 구현은 CameraProvider.cpp , CameraDevice.cppCameraDeviceSession.cpp 에 사용할 수 있습니다. 구현은 여전히 ​​레거시 API 를 사용하는 이전 HAL을 래핑합니다. Android 8.0부터 카메라 HAL 구현은 HIDL API를 사용해야 합니다. 레거시 인터페이스의 사용은 지원되지 않습니다.

입력 유효성 검사

HAL은 카메라 서비스와 다른 리소스에 액세스할 수 있으므로 둘 사이의 경계는 보안 경계로 처리됩니다. 즉, 카메라 서비스에서 전달된 매개변수는 신뢰할 수 없고 살균되지 않은 것으로 간주됩니다. 공격자가 액세스 권한이 없는 데이터에 액세스하거나 권한을 상승시킬 수 있는 보안 취약성을 방지하려면 카메라 HAL이 카메라 서비스에서 HAL로 전달된 매개변수의 유효성을 검사해야 합니다. 여기에는 버퍼 길이 값이 허용 범위 내에 있는지 확인하고 사용하기 전과 하드웨어 또는 커널 드라이버에 전달하기 전에 매개변수를 삭제하는 것이 포함됩니다.

기존 HAL 구성요소

이 섹션에서는 기존 HAL 구성요소의 아키텍처와 HAL을 구현하는 방법을 설명합니다. Android 8.0 이상에서 카메라 HAL 구현은 위에서 설명한 대로 대신 HIDL API를 사용해야 합니다.

아키텍처(레거시)

다음 그림과 목록은 기존 카메라 HAL 구성요소를 설명합니다.

안드로이드 카메라 아키텍처

그림 2. 기존 카메라 아키텍처

앱 프레임워크
앱 프레임워크 수준에는 android.hardware.Camera API를 사용하여 카메라 하드웨어와 상호작용하는 앱의 코드가 있습니다. 내부적으로 이 코드는 해당 JNI 글루 클래스를 호출하여 카메라와 상호 작용하는 기본 코드에 액세스합니다.
JNI
android.hardware.Camera 와 연결된 JNI 코드는 frameworks/base/core/jni/android_hardware_Camera.cpp 에 있습니다. 이 코드는 하위 수준 네이티브 코드를 호출하여 실제 카메라에 대한 액세스 권한을 얻고 프레임워크 수준에서 android.hardware.Camera 개체를 만드는 데 사용되는 데이터를 반환합니다.
기본 프레임워크
frameworks/av/camera/Camera.cpp 에 정의된 기본 프레임워크는 android.hardware.Camera 클래스와 동일한 기본 프레임워크를 제공합니다. 이 클래스는 IPC 바인더 프록시를 호출하여 카메라 서비스에 대한 액세스 권한을 얻습니다.
바인더 IPC 프록시
IPC 바인더 프록시는 프로세스 경계를 ​​통한 통신을 용이하게 합니다. 카메라 서비스를 호출하는 frameworks/av/camera 디렉토리에 있는 3개의 카메라 바인더 클래스가 있습니다. ICameraService 는 카메라 서비스에 대한 인터페이스이고, ICamera 는 특정 열린 카메라 장치에 대한 인터페이스이며, ICameraClient 는 앱 프레임워크에 대한 장치의 인터페이스입니다.
카메라 서비스
frameworks/av/services/camera/libcameraservice/CameraService.cpp 에 있는 카메라 서비스는 HAL과 상호작용하는 실제 코드입니다.
하드웨어 추상화 계층은 카메라 서비스가 호출하고 카메라 하드웨어가 올바르게 작동하도록 구현해야 하는 표준 인터페이스를 정의합니다.
커널 드라이버
카메라 드라이버는 실제 카메라 하드웨어 및 HAL 구현과 상호 작용합니다. 카메라와 드라이버는 디스플레이 및 비디오 녹화에서 카메라 이미지 미리보기를 지원하기 위해 YV12 및 NV21 이미지 형식을 지원해야 합니다.

HAL(기존) 구현

HAL은 카메라 드라이버와 상위 수준 Android 프레임워크 사이에 있으며 앱이 카메라 하드웨어를 올바르게 작동할 수 있도록 구현해야 하는 인터페이스를 정의합니다. HAL 인터페이스는 hardware/libhardware/include/hardware/camera.hhardware/libhardware/include/hardware/camera_common.h 헤더 파일에 정의되어 있습니다.

camera_common.h 는 카메라 ID 및 모든 카메라에 공통적인 속성(즉, 전면 또는 후면 카메라인지 여부)과 같은 카메라에 대한 일반 정보를 얻기 위한 표준 구조인 camera_module 을 정의합니다.

camera.h 에는 android.hardware.Camera 에 해당하는 코드가 포함되어 있습니다. 이 헤더 파일은 HAL 인터페이스를 구현하는 함수에 대한 포인터가 있는 camera_device_ops camera_device 를 선언합니다. 개발자가 설정할 수 있는 카메라 매개변수에 대한 문서는 frameworks/av/include/camera/CameraParameters.h 를 참조하세요. 이러한 매개변수는 HAL에서 int (*set_parameters)(struct camera_device *, const char *parms) 가 가리키는 함수로 설정됩니다.

HAL 구현의 예는 hardware/ti/omap4xxx/camera 에서 Galaxy Nexus HAL 구현을 참조하세요.

공유 라이브러리 구성

HAL 구현을 공유 라이브러리에 올바르게 패키징하도록 Android 빌드 시스템을 설정하고 Android.mk 파일을 만들어 적절한 위치에 복사합니다.

  1. 라이브러리의 소스 파일을 포함할 device/<company_name>/<device_name>/camera 디렉터리를 만듭니다.
  2. Android.mk 파일을 생성하여 공유 라이브러리를 빌드합니다. makefile에 다음 줄이 포함되어 있는지 확인하십시오.
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    라이브러리의 이름은 camera.<device_name> (. .so 는 자동으로 추가됨)으로 지정해야 Android에서 라이브러리를 올바르게 로드할 수 있습니다. 예를 들어, hardware/ti/omap4xxx/Android.mk 에 있는 Galaxy Nexus 카메라용 makefile을 참조하십시오.

  3. 장치의 makefile과 함께 frameworks/native/data/etc 디렉토리에 필요한 기능 XML 파일을 복사하여 장치에 카메라 기능이 있음을 지정합니다. 예를 들어, 장치에 카메라 플래시가 있고 자동 초점이 가능하도록 지정하려면 장치의 <device>/<company_name>/<device_name>/device.mk makefile에 다음 행을 추가하십시오.
    PRODUCT_COPY_FILES := \ ...
    
    PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
    

    장치 makefile의 예는 device/samsung/tuna/device.mk 를 참조하십시오.

  4. device/<company_name>/<device_name>/media_profiles.xmldevice/<company_name>/<device_name>/media_codecs.xml XML 파일에서 카메라의 미디어 코덱, 형식 및 해상도 기능을 선언합니다. 자세한 내용 은 프레임워크에 코덱 노출을 참조하십시오.
  5. 장치의 device/<company_name>/<device_name>/device.mk makefile에 다음 줄을 추가하여 media_profiles.xmlmedia_codecs.xml 파일을 적절한 위치에 복사합니다.
    # media config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_profiles.xml:system/etc/media_profiles.xml
    
    # media codec config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_codecs.xml:system/etc/media_codecs.xml
    
  6. 기기의 시스템 이미지에 카메라 앱을 포함하려면 기기의 device/<company>/<device>/device.mk makefile에 있는 PRODUCT_PACKAGES 변수에 지정하세요.
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...