กล้อง

ไอคอนกล้อง Android HAL

เลเยอร์ที่เป็นนามธรรมของฮาร์ดแวร์กล้อง (HAL) ของ Android จะเชื่อมต่อ API เฟรมเวิร์กของกล้องระดับสูงใน กล้อง 2 กับไดรเวอร์และฮาร์ดแวร์ของกล้องที่ทำงานอยู่ ระบบย่อยของกล้องรวมถึงการใช้งานสำหรับส่วนประกอบไปป์ไลน์ของกล้องในขณะที่ HAL ของกล้องมีอินเทอร์เฟซสำหรับใช้ในการใช้งานเวอร์ชันของส่วนประกอบเหล่านี้

สถาปัตยกรรม

รูปภาพและรายการต่อไปนี้อธิบายส่วนประกอบ HAL

สถาปัตยกรรมกล้อง Android

รูปที่ 1. สถาปัตยกรรมกล้อง

เฟรมเวิร์กแอพ
ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้ Camera 2 API เพื่อโต้ตอบกับฮาร์ดแวร์ของกล้อง ภายในโค้ดนี้เรียกอินเทอร์เฟซ Binder ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดเนทีฟที่โต้ตอบกับกล้อง
AIDL
อินเทอร์เฟซเครื่องผูกที่เชื่อมโยงกับ CameraService สามารถพบได้ที่ frameworks/av/camera/aidl/android/hardware รหัสที่สร้างขึ้นจะเรียกรหัสดั้งเดิมระดับล่างเพื่อเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้าง CameraDevice และในที่สุดวัตถุ CameraCaptureSession ที่ระดับเฟรมเวิร์ก
เฟรมเวิร์กดั้งเดิม
เฟรมเวิร์กนี้อยู่ใน frameworks/av/ มีเนทีฟที่เทียบเท่ากับ CameraDevice และ CameraCaptureSession ดู การอ้างอิง NDK camera2 ด้วย
อินเทอร์เฟซ IPC ของ Binder
อินเทอร์เฟซ IPC Binder ช่วยอำนวยความสะดวกในการสื่อสารเหนือขอบเขตของกระบวนการ มีคลาสตัวผูกกล้องหลายคลาสอยู่ใน frameworks/av/camera/camera/aidl/android/hardware ที่เรียกใช้บริการกล้อง ICameraService คือส่วนต่อประสานกับบริการกล้อง ICameraDeviceUser เป็นส่วนต่อประสานกับอุปกรณ์กล้องที่เปิดอยู่โดยเฉพาะ และ ICameraServiceListener และ ICameraDeviceCallbacks เป็นการเรียกกลับของ CameraService และ CameraDevice ตามลำดับไปยังเฟรมเวิร์กของแอปพลิเคชัน
บริการกล้อง
บริการกล้อง ซึ่งอยู่ใน frameworks/av/services/camera/libcameraservice/CameraService.cpp เป็นรหัสจริงที่โต้ตอบกับ HAL
ฮาล
เลเยอร์ที่เป็นนามธรรมของฮาร์ดแวร์กำหนดอินเทอร์เฟซมาตรฐานที่บริการกล้องเรียกใช้และคุณต้องนำไปใช้เพื่อให้ฮาร์ดแวร์ของกล้องทำงานได้อย่างถูกต้อง

การนำ HAL . ไปปฏิบัติ

HAL อยู่ระหว่างไดรเวอร์กล้องและเฟรมเวิร์ก Android ระดับสูงกว่า และกำหนดอินเทอร์เฟซที่คุณต้องติดตั้งเพื่อให้แอปสามารถใช้งานฮาร์ดแวร์ของกล้องได้อย่างถูกต้อง อินเทอร์เฟซ HIDL สำหรับ Camera HAL ถูกกำหนดไว้ใน ฮาร์ดแวร์/อินเทอร์เฟซ/กล้อง

HAL ที่ผูกมัดโดยทั่วไปต้องใช้อินเทอร์เฟซ HIDL ต่อไปนี้:

  • ICameraProvider : สำหรับระบุอุปกรณ์แต่ละเครื่องและจัดการสถานะ
  • ICameraDevice : ส่วนต่อประสานอุปกรณ์กล้อง
  • ICameraDeviceSession : อินเทอร์เฟซเซสชันอุปกรณ์กล้องที่ใช้งานอยู่

การใช้งาน HIDL อ้างอิงมีให้สำหรับ CameraProvider.cpp , CameraDevice.cpp และ CameraDeviceSession.cpp การใช้งานครอบคลุม HAL เก่าที่ยังคงใช้ API เดิม เริ่มต้นด้วย Android 8.0 การใช้งาน Camera HAL ต้องใช้ HIDL API ไม่รองรับการใช้อินเทอร์เฟซดั้งเดิม

การตรวจสอบอินพุต

เนื่องจาก HAL มีการเข้าถึงทรัพยากรที่แตกต่างจากบริการกล้อง ขอบเขตระหว่างทั้งสองจึงถือเป็นขอบเขตความปลอดภัย ซึ่งหมายความว่าพารามิเตอร์ที่ส่งมาจากบริการกล้องถือว่าไม่น่าเชื่อถือและไม่ถูกสุขอนามัย เพื่อป้องกันช่องโหว่ด้านความปลอดภัยที่อนุญาตให้ผู้โจมตีสามารถยกระดับสิทธิ์หรือเข้าถึงข้อมูลที่ไม่ได้ตั้งใจให้เข้าถึงได้ กล้อง HAL จะต้องตรวจสอบความถูกต้องของพารามิเตอร์ที่ส่งผ่านจากบริการกล้องไปยัง HAL ซึ่งรวมถึงการตรวจสอบว่าค่าความยาวบัฟเฟอร์อยู่ในช่วงที่อนุญาตและฆ่าเชื้อพารามิเตอร์ก่อนใช้งานและก่อนส่งต่อไปยังฮาร์ดแวร์หรือไดรเวอร์เคอร์เนล

ส่วนประกอบ HAL ดั้งเดิม

ส่วนนี้อธิบายสถาปัตยกรรมของส่วนประกอบ HAL แบบเดิมและวิธีการใช้ HAL การใช้งาน Camera HAL บน Android 8.0 ขึ้นไปต้องใช้ HIDL API แทน ดังที่อธิบายไว้ข้างต้น

สถาปัตยกรรม (มรดก)

รูปภาพและรายการต่อไปนี้อธิบายส่วนประกอบ HAL ของกล้องรุ่นเก่า

สถาปัตยกรรมกล้อง Android

รูปที่ 2 สถาปัตยกรรมกล้องรุ่นเก่า

เฟรมเวิร์กแอพ
ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้ android.hardware.Camera API เพื่อโต้ตอบกับฮาร์ดแวร์ของกล้อง ภายใน รหัสนี้เรียกคลาสกาว JNI ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดเนทีฟที่โต้ตอบกับกล้อง
JNI
รหัส JNI ที่เชื่อมโยงกับ android.hardware.Camera อยู่ใน frameworks/base/core/jni/android_hardware_Camera.cpp รหัสนี้เรียกรหัสดั้งเดิมระดับล่างเพื่อเข้าถึงกล้องจริงและส่งคืนข้อมูลที่ใช้ในการสร้างวัตถุ android.hardware.Camera ที่ระดับเฟรมเวิร์ก
เฟรมเวิร์กดั้งเดิม
เฟรมเวิร์กดั้งเดิมที่กำหนดไว้ใน frameworks/av/camera/Camera.cpp ให้เนทีฟเทียบเท่ากับคลาส android.hardware.Camera คลาสนี้เรียกพร็อกซี Binder IPC เพื่อเข้าถึงบริการกล้อง
สารบัญ IPC พร็อกซี่
พร็อกซีสารยึดเกาะ IPC อำนวยความสะดวกในการสื่อสารข้ามขอบเขตของกระบวนการ มีคลาสตัวผูกกล้องสามคลาสที่อยู่ในไดเร็กทอรี frameworks/av/camera ที่เรียกใช้บริการกล้อง ICameraService คืออินเทอร์เฟซสำหรับบริการกล้อง ICamera คืออินเทอร์เฟซไปยังอุปกรณ์กล้องที่เปิดอยู่โดยเฉพาะ และ ICameraClient คืออินเทอร์เฟซของอุปกรณ์กลับไปยังเฟรมเวิร์กของแอป
บริการกล้อง
บริการกล้อง ซึ่งอยู่ใน frameworks/av/services/camera/libcameraservice/CameraService.cpp เป็นรหัสจริงที่โต้ตอบกับ HAL
ฮาล
เลเยอร์ที่เป็นนามธรรมของฮาร์ดแวร์กำหนดอินเทอร์เฟซมาตรฐานที่บริการกล้องเรียกใช้และคุณต้องนำไปใช้เพื่อให้ฮาร์ดแวร์ของกล้องทำงานได้อย่างถูกต้อง
ไดรเวอร์เคอร์เนล
ไดรเวอร์ของกล้องจะโต้ตอบกับฮาร์ดแวร์ของกล้องจริงและการใช้งาน HAL ของคุณ กล้องและไดรเวอร์ต้องรองรับรูปแบบภาพ YV12 และ NV21 เพื่อให้รองรับการแสดงตัวอย่างภาพของกล้องบนจอแสดงผลและการบันทึกวิดีโอ

การนำ HAL ไปปฏิบัติ (ดั้งเดิม)

HAL อยู่ระหว่างไดรเวอร์กล้องและเฟรมเวิร์ก Android ระดับสูงกว่า และกำหนดอินเทอร์เฟซที่คุณต้องติดตั้งเพื่อให้แอปสามารถใช้งานฮาร์ดแวร์ของกล้องได้อย่างถูกต้อง อินเทอร์เฟซ HAL ถูกกำหนดไว้ในไฟล์ส่วนหัว hardware/libhardware/include/hardware/camera.h และ hardware/libhardware/include/hardware/camera_common.h

camera_common.h กำหนด camera_module ซึ่งเป็นโครงสร้างมาตรฐานเพื่อรับข้อมูลทั่วไปเกี่ยวกับกล้อง เช่น ID ของกล้องและคุณสมบัติทั่วไปของกล้องทั้งหมด (นั่นคือ ไม่ว่าจะเป็นกล้องหน้าหรือกล้องหลัง)

camera.h มีรหัสที่สอดคล้องกับ android.hardware.Camera ไฟล์ส่วนหัวนี้ประกาศโครงสร้าง camera_device ที่มี camera_device_ops พร้อมตัวชี้ไปยังฟังก์ชันที่ใช้อินเทอร์เฟซ HAL สำหรับเอกสารเกี่ยวกับพารามิเตอร์ของกล้องที่นักพัฒนาสามารถตั้งค่าได้ โปรดดูที่ frameworks/av/include/camera/CameraParameters.h พารามิเตอร์เหล่านี้ถูกตั้งค่าด้วยฟังก์ชันที่ชี้ไปที่ int (*set_parameters)(struct camera_device *, const char *parms) ใน HAL

สำหรับตัวอย่างการใช้งาน HAL โปรดดูการใช้งาน Galaxy Nexus HAL ใน hardware/ti/omap4xxx/camera

การกำหนดค่าไลบรารีที่ใช้ร่วมกัน

ตั้งค่าระบบบิลด์ Android เพื่อรวมแพ็คเกจการใช้งาน HAL ลงในไลบรารีที่ใช้ร่วมกันอย่างถูกต้อง และคัดลอกไปยังตำแหน่งที่เหมาะสมโดยสร้างไฟล์ 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 จึงสามารถโหลดไลบรารีได้อย่างถูกต้อง ตัวอย่างเช่น ดู makefile สำหรับกล้อง Galaxy Nexus ที่อยู่ใน hardware/ti/omap4xxx/Android.mk

  3. ระบุว่าอุปกรณ์ของคุณมีคุณสมบัติกล้องโดยคัดลอกไฟล์ XML คุณสมบัติที่จำเป็นในไดเร็กทอรี frameworks/native/data/etc ด้วย makefile ของอุปกรณ์ของคุณ ตัวอย่างเช่น หากต้องการระบุว่าอุปกรณ์ของคุณมีแฟลชกล้องและสามารถโฟกัสอัตโนมัติได้ ให้เพิ่มบรรทัดต่อไปนี้ใน <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. ประกาศตัวเข้ารหัสสื่อ รูปแบบ และความละเอียดของกล้องของคุณในไฟล์ XML device/<company_name>/<device_name>/media_profiles.xml and device/<company_name>/<device_name>/media_codecs.xml สำหรับรายละเอียด โปรดดู การเปิดเผยตัวแปลงสัญญาณไปยังเฟรมเวิ ร์ก
  5. เพิ่มบรรทัดต่อไปนี้ในอุปกรณ์ของคุณ device/<company_name>/<device_name>/device.mk makefile เพื่อคัดลอกไฟล์ media_profiles.xml และ media_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. หากต้องการรวมแอปกล้องในอิมเมจระบบของอุปกรณ์ ให้ระบุในตัวแปร PRODUCT_PACKAGES ในอุปกรณ์ของ device/<company>/<device>/device.mk makefile:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...