1. 程式人生 > >Android [Camera 原始碼] 概述(overview) Google官方文件(一)

Android [Camera 原始碼] 概述(overview) Google官方文件(一)

Google原始碼網地址連結:https://source.android.com/devices/camera

看了幾天Camera HAL的實現以及底層的camera驅動/binder驅動,之間的Camera Binder傳輸,訊息Event傳送機制,搞得頭暈腦脹,每個模組都涉及很多方面的知識,經常看到有些地方就卡主,不知道方向了。程式碼看得越多,追得越多,越覺得Android Camera的完整的工作架構是一個非常龐大的工程,不能盲目追程式碼,這樣會沉浸在程式碼海里面,看不到總體架構。沒辦法,學不下去了,就想到還是找些資料看看吧,於是就翻牆去官網找到這部分的介紹,如獲至寶的感覺。看看下圖官網的介面,看中文版可以把頁面拉到最下面,在右下角有一個語言選擇的選項,可以直接選擇簡體中文,看來google還是挺人性化的嘛,專門為文件翻譯了中文的。

這個地址要翻牆才能看,這裡轉載給不能翻牆的朋友看看吧,自己有時也能直接開啟看,省得去翻牆,能翻牆的可以直接去看看原文。Google描述的設計框架只介紹很難明白,大家可以結合自己的程式碼,結合官方的文件設計框架來理解。

 

 

該Google Camera的文件為系列文章,文章列表:

overview

Camera3

HAL Subsystem

Metadata and Controls

3A Modes and State

Output and Cropping

Errors and Streams

Request Creation

External USB Cameras

Multi-Camera Support

Motion Tracking

Session Parameters

Single Producer,Multiple Consumer

Version Support

 

好了,廢話不多說了,這裡將語言選擇為簡體中文轉過來。


相機

Android 的相機硬體抽象層 (HAL) 可將 Camera 2 中較高級別的相機框架 API 連線到底層的相機驅動程式和硬體。相機子系統包括相機管道元件的實現,而相機 HAL 則可提供用於實現您的這些元件版本的介面。

  • 注意:如果您要在搭載 Android 8.0 或更高版本的裝置上實現相機 HAL,則必須使用 HIDL 介面。要了解舊版元件,請參閱舊版 HAL 元件。

 

架構


下列圖表和列表說明了 HAL 元件:

圖 1. 相機架構

應用框架

應用程式碼位於應用框架級別,它使用 Camera 2 API 與相機硬體進行互動。在內部,這些程式碼會呼叫相應的 Binder 介面,以訪問與相機互動的原生程式碼。

AIDL
與 CameraService 關聯的 Binder 介面可在 frameworks/av/camera/aidl/android/hardware 中找到。 生成的程式碼會呼叫較低級別的原生程式碼以獲取對實體相機的訪問許可權,並返回用於在框架級別建立 CameraDevice 並最終建立 CameraCaptureSession 物件的資料。

原生框架
此框架位於 frameworks/av/ 中,並提供相當於 CameraDevice 和 CameraCaptureSession 類的原生類。另請參閱 NDK camera2 參考。

Binder IPC 介面
IPC binder 介面用於實現跨越程序邊界的通訊。呼叫相機服務的若干個相機 Binder 類位於 frameworks/av/camera/camera/aidl/android/hardware 目錄中。 ICameraService 是相機服務的介面;ICameraDeviceUser 是已開啟的特定相機裝置的介面;ICameraServiceListener 和 ICameraDeviceCallbacks 分別是對應用框架的 CameraService 和 CameraDevice 回撥。

相機服務
位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp 下的相機服務是與 HAL 進行互動的實際程式碼。

HAL
硬體抽象層定義了由相機服務呼叫、且您必須實現以確保相機硬體正常執行的標準介面。

 

實現 HAL


HAL 位於相機驅動程式和更高級別的 Android 框架之間,它定義您必須實現的介面,以便應用可以正確地操作相機硬體。從 Android 8.0 開始,相機 HAL 介面是 Project Treble 的一部分,相應的 HIDL 介面在 hardware/interfaces/camera 中定義。

典型的繫結式 HAL 必須實現以下 HIDL 介面:

  • ICameraProvider:用於列舉單個裝置並管理其狀態。
  • ICameraDevice:相機裝置介面。
  • ICameraDeviceSession:活躍的相機裝置會話介面。

參考 HIDL 實現適用於 CameraProvider.cpp、CameraDevice.cpp 和 CameraDeviceSession.cpp。該實現封裝了仍在使用舊版 API 的舊 HAL。從 Android 8.0 開始,相機 HAL 實現必須使用 HIDL API;不支援使用舊版介面。

要詳細瞭解 Treble 和 HAL 開發,請參閱 Treble 資源。

 

舊版 HAL 元件


此部分介紹了舊版 HAL 元件的架構以及如何實現 HAL。搭載 Android 8.0 或更高版本的裝置上的相機 HAL 實現必須改用 HIDL API(如上所述)。

架構(舊版)
下列圖表和列表說明了舊版相機 HAL 元件:

圖 1. 相機架構

應用框架
應用程式碼位於應用框架級別,它利用 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 binder 代理,以獲取對相機服務的訪問許可權。

Binder IPC 代理
IPC binder 代理用於促進跨越程序邊界的通訊。呼叫相機服務的 3 個相機 binder 類位於 frameworks/av/camera 目錄中。ICameraService 是相機服務的介面,ICamera 是已開啟的特定相機裝置的介面,ICameraClient 是指回應用框架的裝置介面。

相機服務
位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp 下的相機服務是與 HAL 進行互動的實際程式碼。

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 結構,該結構又反過來包含一個帶函式指標(可實現 HAL 介面)的 camera_device_ops 結構。有關開發者可以設定的相機引數的文件,請參閱 frameworks/av/include/camera/CameraParameters.h。通過 HAL 中的 int (*set_parameters)(struct camera_device *, const char *parms) 來設定這些引數以及指向的函式。

有關 HAL 實現的示例,請參閱 hardware/ti/omap4xxx/camera 中的 Galaxy Nexus HAL 實現。

配置共享庫
設定 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 可以正確載入庫。例如,請參閱 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.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.要將相機應用包含在裝置的系統映像中,請在裝置的 device/<company>/<device>/device.mk Makefile 中的 PRODUCT_PACKAGES 變數中指定該應用:

PRODUCT_PACKAGES := \
Gallery2 \
...