Android Camera Module
CAMERA_MODULE_API_VERSION_2_4
- Torch mode. Framework 可以打开 flash 而不需要开启 camera device。Camera device 访问 falsh unit 的优先级高于 camera module, 打开 camera device 将会关闭 troch。如果有 资源冲突,例如调用 open() 打开 camera device,camera HAL module 必须通知 framework torch mode 的 status 改变了。
- External camera(hot-plug camera). API updates 规定,只有在 camera 已经 连接 并且 ready 时 camera static info 才是可用的。
- Camera arbitration hints.(冲裁提示) 该版本的 module 增加 显式地指示 可以同时打开和使用的 camera devices 的个数。要指定有效的 devices 组合,resource_cost 和 conflicting_devices 字段应该被设置,并且通过 get_camera_info 调用返回。
- Module initialization method. 该函数被 camera service 在 HAL module 被加载后调用,允许 HAL 完成 one-time 的初始化工作。在其他 module methods 之前被调用。
camera_info
typedef struct camera_info {
int facing;
int orientation;
uint32_t device_version;
const camera_metadata_t *static_camera_characteristics;
int resource_cost;
char** conflicting_devices;
size_t conflicting_devices_length;
} camera_info_t;
facing
- CAMERA_MODULE_API_VERSION_2_3 之下: CAMERA_FACING_FRONT, CAMERA_FACING_BACK
- CAMERA_MODULE_API_VERSION_2_4 之上:CAMERA_FACING_FRONT, CAMERA_FACING_BACK, CAMERA_FACING_EXTERNAL
orientation
Image 显示时需要顺时针旋转的角度。可能是 0, 90, 180, 270.
- CAMERA_MODULE_API_VERSION_2_3 之下:所有的 Camera Module有效
- CAMERA_MODULE_API_VERSION_2_4 之上:CAMERA_FACING_EXTERNAL无效,其他 有效
device_version
The value of camera_device_t.common.version.
- CAMERA_MODULE_API_VERSION_1_0: 该字段无效
- CAMERA_MODULE_API_VERSION_2_0: 有效
static_camera_characteristics
The camera's fixed characteristics.
- system/media/camera/socs/docs.html 指定的 static camera metadata.
- 这应该是 一个排序的 metadata buffer,可能被调用者 修改或释放.
- 该指针应该在 camera module 的生命周期内保持有效, 其中的值可能在 get_camera_info() 之后不会改变.
- CAMERA_MODULE_API_VERSION_1_0: 无效。
- CAMERA_MODULE_API_VERSION_2_0: 有效。
resource_cost
使用 camera 的总资源“成本”,表示为 [0-100] 的整数,100 表示Camera subsystem 的限制瓶颈共享资源的总使用。这可能时一个非常粗略的估计,用来提示 camera service 决定禁止多个应用同时打开不同的 cameras.
camera service必须能够同时打开和使用的 camera devices 的 总的资源成本 <=100. 为了确定成本,每个 camera device 必须假设以最大资源消耗 framerate 和stream size被配置操作,通过 camera metadata 暴露。
camera service 可能试图同时打开的 camera device 的总资源消耗 > 100. 这可能成功或失败. 如果成功,由于 资源限制 该配置组合是不被支持,haveing multiple open devices should fail during the configure calls. 如果总资源消耗 <= 100, 不应该失败。
该字段用来决定是否允许 应用 后台使用 camera device 当其他应用在使用 camera device 时。注意:禁止多个应用同时打开同一个 camera devices.
例如:
Camera Device 0 = Back Camera
Camera Device 1 = Front Camera
同时使用两个设备可能由于 ISP 带宽限制导致帧率降低。
Configuration:
Camera Device 0 - resource_cost = 51
conflicting_devices = null
Camera Device 1 - resource_cost = 51
conflicting_devices = null
Result:
由于 resource const > 100,如果一个更高优先级的应用打开了一个 camera device,那么低优先级的应用无法打开另一个 camera device. 如果低优先级的应用正在使用高优先级应用试图打开的 camera device,那么低优先级的应用将会被强制 disconnecte.
如果 最高优先级的应用试图打开两个设备,但是可能打开或配置失败。
* Ex. 2: Camera Device 0 = Left Back Camera
* Camera Device 1 = Right Back Camera
* Camera Device 2 = Combined stereo camera using both right and left
* back camera sensors used by devices 0, and 1
* Camera Device 3 = Front Camera
* - Due to do hardware constraints, up to two cameras may be open at once. The
* combined stereo camera may never be used at the same time as either of the
* two back camera devices (device 0, 1), and typically requires too much
* bandwidth to use at the same time as the front camera (device 3).
*
* Configuration:
*
* Camera Device 0 - resource_cost = 50
* conflicting_devices = { 2 }
* Camera Device 1 - resource_cost = 50
* conflicting_devices = { 2 }
* Camera Device 2 - resource_cost = 100
* conflicting_devices = { 0, 1 }
* Camera Device 3 - resource_cost = 50
* conflicting_devices = null
*
* Result:
*
* Based on the conflicting_devices fields, the camera service guarantees that
* the following sets of open devices will never be allowed: { 1, 2 }, { 0, 2 }.
*
* Based on the resource_cost fields, if a high-priority foreground application
* is using camera device 0, a background application would be allowed to open
* camera device 1 or 3 (but would be forced to disconnect it again if the
* foreground application opened another device).
*
* The highest priority application may still attempt to simultaneously open
* devices 0, 2, and 3, but the HAL may fail in open or configure calls for
* this combination.
* Ex. 3: Camera Device 0 = Back Camera
* Camera Device 1 = Front Camera
* Camera Device 2 = Low-power Front Camera that uses the same
* sensor as device 1, but only exposes image stream
* resolutions that can be used in low-power mode
* - Using both front cameras (device 1, 2) at the same time is impossible due
* a shared physical sensor. Using the back and "high-power" front camera
* (device 1) may be impossible for some stream configurations due to hardware
* limitations, but the "low-power" front camera option may always be used as
* it has special dedicated hardware.
*
* Configuration:
*
* Camera Device 0 - resource_cost = 100
* conflicting_devices = null
* Camera Device 1 - resource_cost = 100
* conflicting_devices = { 2 }
* Camera Device 2 - resource_cost = 0
* conflicting_devices = { 1 }
* Result:
*
* Based on the conflicting_devices fields, the camera service guarantees that
* the following sets of open devices will never be allowed: { 1, 2 }.
*
* Based on the resource_cost fields, only the highest priority application
* may attempt to open both device 0 and 1 at the same time. If a higher-priority
* application is not using device 1 or 2, a low-priority background application
* may open device 2 (but will be forced to disconnect it if a higher-priority
* application subsequently opens device 1 or 2).
- CAMERA_MODULE_API_VERSION_2_3 无效
- CAMERA_MODULE_API_VERSION_2_4 有效
conflicting_devices
不能同时打开的 Camera ID 数组.
- CAMERA_MODULE_API_VERSION_2_3 无效
- CAMERA_MODULE_API_VERSION_2_4 有效
conflicting_devices_length
camera_device_status_t
typedef enum camera_device_status {
CAMERA_DEVICE_STATUS_NOT_PRESENT = 0,
CAMERA_DEVICE_STATUS_PRESENT = 1,
CAMERA_DEVICE_STATUS_ENUMERATING = 2,
} camera_device_status_t;
概述
camera_device_status_t 描述 camera devices 的 current status.通过 Camera HAL 调用 camera_module_callbacks.camera_device_status_change() 函数通知.
在 Module 加载后, framework 会假设 camera devices 进入 CAMERA_DEVICE_STATUS_PRESENT 状态. HAL 应该通过 camera_module_callbacks::camera_device_status_change 通知 framework 最初的 NO_PRESENT 的设备.
* 状态迁移
* PRESENT -> NOT_PRESENT
* NOT_PRESENT -> ENUMERATING
* NOT_PRESENT -> PRESENT
* ENUMERATING -> PRESENT
* ENUMERATING -> NOT_PRESENT
CAMERA_DEVICE_STATUS_NOT_PRESENT
- camera device 处于 尚未连接 状态. open 会返回失败.
- CAMERA_MODULE_API_VERSION_2_3 or lower: get_camera_info 正确返回并且如果 camera 已经连接则需提供相同的信息
- CAMERA_MODULE_API_VERSION_2_4: device 未连接状态通过 get_camera_info 调用 camera device 必须返回 -EINVAL.
CAMERA_DEVICE_STATUS_PRESENT
- 表示 camera devices 处于 connected , opening 将会成功.
- CAMERA_MODULE_API_VERSION_2_3 or lower: get_camera_info 返回的 信息不能更改由于该状态改变. 默认 framewok 假设所有的设备处于该状态.
- CAMERA_MODULE_API_VERSION_2_4: 当 devices status 变为该状态时通过 get_camera_info 返回的信息变为有效.默认,framework会假设所有的设备处于该状态.
CAMERA_DEVICE_STATUS_ENUMERATING
- 表示 camera devices 处于 connected 状态, 但是正在枚举因此打开设备将返回 -EBUSY.
- CAMERA_MODULE_API_VERSION_2_3 or lower:camera 处于 PRESENT 状态,调用 get_camera_info 返回成功.
- CAMERA_MODULE_API_VERSION_2_4: camera devics 处于该状态,get_camera_info 必须返回 -EINVAL, 由于 device 没有 ready.
torch_mode_status_t
typedef enum torch_mode_status {
TORCH_MODE_STATUS_AVAILABLE_OFF = 1,
TORCH_MODE_STATUS_AVAILABLE_ON = 2,
} torch_mode_status_t;
概述
描述 troch mode 的当前状态, 由 HAL 通过 camera_module_callbacks.torch_mode_status_change() 提供.
camera device 的 torch mode status 只有在 camera devices 处于 PRESENT 适用. 当 camera device 处于 NOT_PRESENT 状态时, framework 不会调用 set_torch_mode() 来打开 torch mode.
当 module 加载时,framework会假设 torch mode 处于 TORCH_MODE_STATUS_AVAILABLE_OFF 状态, 前提是 camera devices 处于 PRESENT 并且 android.flash.info.available 已经通过 get_camera_info() 上报为 true.
当 camera device 的状态发生变化时,framework 在以下情况下期望的 Camera HAL module 的行为:
-
之前 disconnected 的 camera device 变为 connected.
在 camera_module_callbacks::camera_device_status_change() 被调用通知 framework camera devices 是 PRESENT, framework 会假设 camera device's torch mode 处于 TORCH_MODE_STATUS_AVAILABLE_OFF 状态. camera HAL module 不需要调用 camera_module_callbacks::torch_mode_status_change() 除非 flash unit 通过调用 set_torch_mode() 变为了 不可用.
-
之前 connected 的 camera 变为 disconnected.
在 camera_module_callbacks::camera_device_status_change() 被调用通知 framework camera device 处于 NOT_PRESENT ,framework 将不会为 处于 disconnected 的 camera device 调用 set_torch_mode() 知道 flash unit 再次变为 available. camera HAL module 不需要调用 camera_module_callbacks::torch_mode_status_change() 来通知 flash unit 变为 不可用.
-
通过 open() 来打开一个 camera device.
camera HAL module 必须为所有的 进入到 TORCH_MODE_STATUS_NOT_AVAILABLE 状态的 flash unit 调用 camera_module_callbacks::torch_mode_status_change() 并且不能通过 set_torch_mode() 再次打开.
在 TORCH_MODE_STATUS_NOT_AVAILABLE 之前 open() 禁止触发 TORCH_MODE_STATUS_AVAILABLE_OFF, 对所有的变为 不可用 的 flash unit.
-
通过 close() 来关闭一个 camera device.
camera HAL module 必须为所有的进入到 TORCH_MODE_STATUS_AVAILABLE_OFF 状态的 flash unit 调用 camera_module_callbacks::torch_mode_status_change() 并且可以通过 set_torch_mode() 再次关闭由于再次调用 close() 时已没有足够的资源用来释放.
注意:
framework 成功调用 set_torch_mode() 后必须触发 TORCH_MODE_STATUS_AVAILABLE_OFF 或 TORCH_MODE_STATUS_AVAILABLE_ON 的回调.并且必须触发 TORCH_MODE_STATUS_AVAILABLE_OFF 回调为之前已经处于打开的 troch mode, 如果HAL不支持 同时多个 torch modes.
TORCH_MODE_STATUS_NOT_AVAILABLE
- flash unit 不再是 available 并且 不能通过 set_torch_mode() 打开 torch mode.
- 如果 troch mode 打开, HAL 将会 在 torch_mode_status_change() 之前关闭.
TORCH_MODE_STATUS_AVAILABLE_OFF
/**
* A torch mode has become off and available to be turned on via
* set_torch_mode(). This may happen in the following
* cases:
* 1. After the resources to turn on the torch mode have become available.
* 2. After set_torch_mode() is called to turn off the torch mode.
* 3. After the framework turned on the torch mode of some other camera
* device and HAL had to turn off the torch modes of any camera devices
* that were previously on.
*/
TORCH_MODE_STATUS_AVAILABLE_OFF = 1,
TORCH_MODE_STATUS_AVAILABLE_ON
/**
* A torch mode has become on and available to be turned off via
* set_torch_mode(). This can happen only after set_torch_mode() is called
* to turn on the torch mode.
*/
camera_module_callbacks_t
typedef struct camera_module_callbacks {
void (*camera_device_status_change)(const struct camera_module_callbacks*,
int camera_id,
int new_status);
void (*torch_mode_status_change)(const struct camera_module_callbacks*,
const char* camera_id,
int new_status);
} camera_module_callbacks_t;
概述
camera_module_callbacks_t 用来通知 framework camera subsystem 的改变.
- CAMERA_MODULE_API_VERSION_2_1: camera_device_status_change()
- CAMERA_MODULE_API_VERSION_2_4: torch_mode_status_change()
camera_device_status_change
- 回调到 framework 通知 特定 camera device 状态的改变.
- 在 module load 时,framework 会假设所有的 camera devices 处于 CAMERA_DEVICE_STATUS_PRESENT 状态.
- HAL 必须调用该方法来通知 framework 任何初始状态为 NO_PRESENT 的 devices.
torch_mode_status_change
- 回调到 framework 通知和 特定 camera device 相关的 flash unit 的状态的改变.
- 在 Module load 时,如果 android.flash.info.available 通过 get_camera_info() 被上报为 ture, framework 会假设 torch mode 处于 TORCH_MODE_STATUS_AVAILABLE_OFF.
camera_module_t
typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
int (*open_legacy)(const struct hw_module_t* module, const char* id,
uint32_t halVersion, struct hw_device_t** device);
int (*set_torch_mode)(const char* camera_id, bool enabled);
int (*init)();
void* reserved[5];
} camera_module_t;
common
所有 moduel 的第一个字段必须是 hw_module_t.
-
common.methods->open 的返回值:
- 0 : 成功
- -ENODEV : 由于 internel error, camera device 不能被打开.
- -EINVAL : 输出参数非法.例如 id 非法,或 module 非法.
- -EBUSY : camera id 对应的 camera device 已经打开.
- -EUSERS : 可以通过次方法或者 open_legacy 可以同时打开的 camera devices 个数都打开了.
所有其他的 返回值 都被认为是 -ENODEV.
get_number_of_cameras
- CAMERA_MODULE_API_VERSION_2_3 or lower: 返回值必须是静态不变的.
- CAMERA_MODULE_API_VERSION_2_4 or higher: 返回值必须是静态的,必须计数 built-in cameras,即 CAMERA_FACING_BACK 或 CAMERA_FACING_FRONT, 必须不能包含 external cameras. framework 将使用 camera_device_status_change 回调来管理 external cameras .
get_camera_info
- static camera information. information 是不变的.
- 返回值:
- 0 : 成功
- -ENODEV: 由于 internal error 导致 information 不能被提供.
- -EINVAL: 输出参数非法.
- CAMERA_MODULE_API_VERSION_2_4: 当 camera 处于 disconnected 状态时, camera id 变为非法.调用该方法由于 camera id 是非法将会返回 -EINVAL 并且 camera static metadata 是 NULL.
set_callbacks:
- 提供以异步通知 framework 的回调函数指针.
- framework 会在 camera module 加载后 调用该方法, 首先调用 get_number_of_cameras() 方法.
- CAMERA_MODULE_API_VERSION_1_0, CAMERA_MODULE_API_VERSION_2_0: framework 可能不会调用该函数.
- CAMERA_MODULE_API_VERSION_2_1: framework 调用合法.
- 返回值:
- 0 : 成功.
- -ENODEV: 由于 internal error 返回失败.
- -EINVAL: 输入参数非法.
get_vendor_tag_ops
- Get methods to query for vendor extension metadata tag information.
- CAMERA_MODULE_API_VERSION_1_x/2_0/2_1: Framework 不会调用该方法.
- CAMERA_MODULE_API_VERSION_2_2: 有效.
open_legacy
- 如果 Camera HAL module 支持多个不同版本的 HAL API, open_legacy 打开一个特定 legacy camera HAL device.
- 例如,如果 camera module 对一个 camera device 同时支持 CAMERA_DEVICE_API_VERSION_1_0 和 CAMERA_DEVICE_API_VERSION_3_2,framework 可以调用该函数打开版本号为 CAMERA_DEVICE_API_VERSION_1_0 的 camera device.
- 这是一个可选的方法. Camera HAL module 不需要为每个 device 支持超过一个 device HAL version,因此调用该 module 的该方法 可能返回-ENOSYS。对所有的较老版本的 HAL device API 是不支持的,可能返回 -EOPNOTSUPP.
- CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2: 无效
- CAMERA_MODULE_API_VERSION_2_3: 有效
- 返回值:
- 0 : 成功
- -ENOSYS : 不支持该方法
- -EOPNOTSUPP : The requested HAL version is not supported by this method.
- -EINVAL: 输入参数无效.
- -EBUSY: camera device 已经打开了.忽略 device HAL version.
- -EUSERS: 当前可打开的最大 camera devices 个数已经被打开了,通过该方法或者 common.methods->open.
set_torch_mode
概述
打开或关闭和给定camera ID相关的 flash unit 的 torch mode. 如果操作成功,HAL 必须通过 camera_module_callbacks.torch_mode_status_change() 通知 framewok 新的 torch state.
camera device 有访问 flash unit 的最后优先级。当存在资源冲突时,例如 open() camera device,HAL module 必须通过 camera_module_callbacks.torch_mode_status_change() 通知 framewok torch mode 已经关闭并且 torch mode state 已经变为 TORCH_MODE_STATUS_NOT_AVAILABLE。当打开 torch mode 的资源再次可用时,HAL module 必须通过 camera_module_callbacks.torch_mode_status_change() 通知 framewok torch mode state 变为 TORCH_MODE_STATUS_AVAILABLE_OFF.
当 framewok 调用 set_torch_mod() 打开 flash unit 的 torch mode 时,并且 HAL 不能支持同时多个 torch modes,HAL 应该由上一个 set_torch_mode() 关闭 torch mode 并且通知 framewok flash unit 的 torch mode state 变为了 TORCH_MODE_STATUS_AVAILABLE_OFF。
Version information
- CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3: 无效
- CAMERA_MODULE_API_VERSION_2_4: 有效
Return values
- 0 : 成功
- -ENOSYS: camera device 不支持该操作. 如果只有 android.flash.info.available 为 false 则返回该值.
- -EBUSY: The camera device is already in use.
- -EUSERS: 打开资源不可用的 torch mode, 通常由于其他的 camera device 占用资源使得 flash unit 不可用.
- -EINVAL: camera_id 非法。
init
概述
在 camera module 加载后,其他方法调用之前由 framewok 调用。如果没有初始化工作,可以设置为 NULL.
可以被实现为完成 one-time 的初始化操作。
version
- CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3: 无效
- CAMERA_MODULE_API_VERSION_2_4: 有效
Return values:
- 0 : On a successful operation.
- -ENODEV: 由于 internal error 无法完成初始化.