接着上一篇:
Camera显示之Hal层的适配(一)
一.基本关系
1.先来看看KTM hal层大概类图关系:
大概类图关系就是这样, 其中和显示相关的类图关系如红线所圈区域。
可以猜测到 与显示相关的逻辑处理应该都会在DisplayClient这个类去实现。
以后app下达有关预览显示相关的东西啊在hal层基本上都是这一条先进行传递命令, 不过总1中我们可以看到CamDevice还有一些衍生类, 这些都是mtk为不同设备做的一些定制, 主要的路径还是如上图所示。
二.接着之前的在CameraClient中的代码:
//!++
else if ( window == 0 ) {
result = mHardware->setPreviewWindow(window);
}
1.setPreviewWindow(window)通过CameraHardwareInterface适配:
mDevice->ops->set_preview_window(mDevice,
buf.get() ? &mHalPreviewWindow.nw : 0);
来实现向hal层下达命令和设置参数。
在这里我们发现传入的是mHalPreviewWindow.nw, 而不是我们之前所讲述的ANativeWindow 这是因为mHalPreviewWindow.nw将ANativeWindow的一些流的操作进行封装, 使之操作更加简便。
mHalPreviewWindow.nw的定义:
struct camera_preview_window {
struct preview_stream_ops nw;
void *user;
};
就是结构体:struct :
typedef struct preview_stream_ops {
int (*dequeue_buffer)(struct preview_stream_ops* w,
buffer_handle_t** buffer, int *stride);
int (*enqueue_buffer)(struct preview_stream_ops* w,
buffer_handle_t* buffer);
int (*cancel_buffer)(struct preview_stream_ops* w,
buffer_handle_t* buffer);
int (*set_buffer_count)(struct preview_stream_ops* w, int count);
int (*set_buffers_geometry)(struct preview_stream_ops* pw,
int w, int h, int format);
int (*set_crop)(struct preview_stream_ops *w,
int left, int top, int right, int bottom);
int (*set_usage)(struct preview_stream_ops* w, int usage);
int (*set_swap_interval)(struct preview_stream_ops *w, int interval);
int (*get_min_undequeued_buffer_count)(const struct preview_stream_ops *w,
int *count);
int (*lock_buffer)(struct preview_stream_ops* w,
buffer_handle_t* buffer);
// Timestamps are measured in nanoseconds, and must be comparable
// and monotonically increasing between two frames in the same
// preview stream. They do not need to be comparable between
// consecutive or parallel preview streams, cameras, or app runs.
int (*set_timestamp)(struct preview_stream_ops *w, int64_t timestamp);
对显示流的操作都是通过这些函数实现的,而mHalPreviewWindow中实现了具体操的方法, 在这些方法的实现中实现对作ANativeWindow的操作。 而在hal端就是通过mHalPreviewWindow.nw 进行对ANativeWindow的具体操作。
基本类图关系:
2.继续1中的:
mDevice->ops->set_preview_window(mDevice,
buf.get() ? &mHalPreviewWindow.nw : 0);
我已经知道了mHalPreviewWindow.nw为传入的一个重要参数mHalPreviewWindow.nw 为preview_stream_ops。
继续看看set_preview_window这个方法。 我们有上篇文章知道ops是ICamDevice的一个成员gCameraDevOps,类型为camera_device_ops_t:
可以看到:
static camera_device_ops_t const gCameraDevOps = {
set_preview_window: camera_set_preview_window,
set_callbacks: camera_set_callbacks,
enable_msg_type: camera_enable_msg_type,
disable_msg_type: camera_disable_msg_type,
msg_type_enabled: camera_msg_type_enabled,
start_preview: camera_start_preview,
stop_preview: camera_stop_preview,
preview_enabled: camera_preview_enabled,
store_meta_data_in_buffers: camera_store_meta_data_in_buffers,
start_recording: camera_start_recording,
stop_recording: camera_stop_recording,
recording_enabled: camera_recording_enabled,
release_recording_frame: camera_release_recording_frame,
auto_focus: camera_auto_focus,
cancel_auto_focus: camera_cancel_auto_focus,
take_picture: camera_take_picture,
cancel_picture: camera_cancel_picture,
set_parameters: camera_set_parameters,
get_parameters: camera_get_parameters,
put_parameters: camera_put_parameters,
send_command: camera_send_command,
release: camera_release,
dump: camera_dump,
};
gCameraDevOps 中的函数地址映射到ICamDevice中的函数实现。
所以 :ops->set_preview_window(mDevice, buf.