กล้องถ่ายรูป

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

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

สถาปัตยกรรม

รูปภาพและรายการต่อไปนี้อธิบายคอมโพเนนต์ HAL

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

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

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

ติดตั้งใช้งาน HAL

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

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

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

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

การตรวจสอบข้อมูลที่ป้อน

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

คอมโพเนนต์ HAL เดิม

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

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

รูปภาพและรายการต่อไปนี้อธิบายคอมโพเนนต์ HAL ของกล้องรุ่นเดิม

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

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

เฟรมเวิร์กแอป
ที่ระดับเฟรมเวิร์กของแอปคือโค้ดของแอป ซึ่งใช้ android.hardware.Camera API เพื่อโต้ตอบกับฮาร์ดแวร์กล้อง ภายใน โค้ดนี้จะเรียกคลาส JNI Glue ที่เกี่ยวข้องเพื่อเข้าถึงโค้ดแบบเนทีฟที่โต้ตอบกับกล้อง
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 ของ Binder
พร็อกซี Binder ของ IPC ช่วยให้การสื่อสารข้ามขอบเขตของกระบวนการเป็นไปได้ มีคลาส Binder ของกล้อง 3 คลาสซึ่งอยู่ในไดเรกทอรี frameworks/av/camera ที่เรียกใช้บริการกล้อง ICameraService คืออินเทอร์เฟซของบริการกล้อง ICamera คืออินเทอร์เฟซของอุปกรณ์กล้องที่เปิดอยู่ และ ICameraClient คืออินเทอร์เฟซของอุปกรณ์ที่กลับไปที่ เฟรมเวิร์กของแอป
บริการกล้อง
บริการกล้องซึ่งอยู่ที่ frameworks/av/services/camera/libcameraservice/CameraService.cpp คือโค้ดจริงที่โต้ตอบกับ HAL
HAL
Hardware Abstraction Layer กำหนดอินเทอร์เฟซมาตรฐานที่บริการกล้องเรียกใช้และคุณต้องใช้เพื่อให้ฮาร์ดแวร์กล้องทำงานได้อย่างถูกต้อง
ไดรเวอร์เคอร์เนล
ไดรเวอร์ของกล้องจะโต้ตอบกับฮาร์ดแวร์กล้องจริงและการติดตั้งใช้งาน 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 ซึ่งเป็นโครงสร้างมาตรฐาน สำหรับรับข้อมูลทั่วไปเกี่ยวกับกล้อง เช่น รหัสกล้อง และพร็อพเพอร์ตี้ที่ใช้ร่วมกันในกล้องทุกตัว (เช่น กล้องหน้าหรือ กล้องหลัง)

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 ได้ที่การติดตั้งใช้งานสำหรับ HAL ของ Galaxy Nexus ใน 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. ประกาศความสามารถของตัวแปลงรหัส รูปแบบ และความละเอียดของสื่อในกล้องในไฟล์ device/<company_name>/<device_name>/media_profiles.xml และ device/<company_name>/<device_name>/media_codecs.xml 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 \
    ...