Camera Hal OEM模块 ---- cmr_grab.c
文章目录
- 1,cmr_grab_init
- 1.1,open 节点
- 1.2,维护mutex
- 1.3, SPRD_IMG_IO_GET_DCAM_RES
- 1.4,创建thread
- 2,cmr_grab_deinit
- 2.1 kill thread ,指令 SPRD_IMG_STOP_DCAM
- 2.2 指令 SPRD_IMG_IO_PUT_DCAM_RES
- 2.3 mutex destory
- 3,一些指令
- 4,帧数据回调
- 5,一些 cfg
- 6,cmr_grab_cap_start 和 cmr_grab_cap_stop
- 7,pause 和 resume
- 8,cmr_grab_start_capture 和 cmr_grab_stop_capture
- 9,cmr_grab_cap_resume 和 cmr_grab_cap_pause
- 10,关键函数:cmr_grab_thread_proc
- 10.1 irq_type 含义
- 10.2 channel_id 的概念
- 10.3 封装帧数据的值
- 10.4 回调
cmr_grab.c是oem端拿到帧数据最底层的地方,直接操作节点
CMR_GRAB_DEV_NAME “/dev/sprd_image”
我们在hal端拿到的预览和拍照的数据都来自这个文件。这里是原始的数据,hal和oem在从cmr_grab中拿到数据后在跑各种算法。
cmr_grab还有大量的 ioctl 操作。
下面我们来看下cmr_grab的重要内容
1,cmr_grab_init
cmr_int cmr_grab_init(struct grab_init_param *init_param_ptr,cmr_handle *grab_handle)
1.1,open 节点
p_grab->fd = open(CMR_GRAB_DEV_NAME, O_RDWR, 0);
1.2,维护mutex
ret = pthread_mutex_init(&p_grab->cb_mutex, NULL);
ret = pthread_mutex_init(&p_grab->dcam_mutex, NULL);
ret = pthread_mutex_init(&p_grab->status_mutex, NULL);
ret = pthread_mutex_init(&p_grab->path_mutex[channel_id], NULL);
1.3, SPRD_IMG_IO_GET_DCAM_RES
ret = ioctl(p_grab->fd, SPRD_IMG_IO_GET_DCAM_RES, &res);
1.4,创建thread
ret = cmr_grab_create_thread((cmr_handle)p_grab);
2,cmr_grab_deinit
cmr_int cmr_grab_deinit(cmr_handle grab_handle)
2.1 kill thread ,指令 SPRD_IMG_STOP_DCAM
ret = cmr_grab_kill_thread(grab_handle);op.cmd = SPRD_IMG_STOP_DCAM;
op.sensor_id = p_grab->init_param.sensor_id;
cnt = write(p_grab->fd, &op, sizeof(struct sprd_img_write_op));
2.2 指令 SPRD_IMG_IO_PUT_DCAM_RES
ret = ioctl(p_grab->fd, SPRD_IMG_IO_PUT_DCAM_RES, &res);
2.3 mutex destory
pthread_mutex_destroy(&p_grab->cb_mutex);
pthread_mutex_destroy(&p_grab->dcam_mutex);
pthread_mutex_destroy(&p_grab->status_mutex);
pthread_mutex_destroy(&p_grab->path_mutex[channel_id]);
老规矩,init 与 deinit 的操作基本是相对的,创建了什么就要销毁什么
3,一些指令
SPRD_IMG_IO_GET_IOMMU_STATUS
SPRD_IMG_IO_SET_CAM_SECURITY
SPRD_IMG_IO_SET_CAP_ZSL_INFO
SPRD_ISP_IO_SET_PULSE_LINE
SPRD_ISP_IO_SET_VCM_LOG
SPRD_ISP_IO_SET_NEXT_VCM_POS
4,帧数据回调
cmr_grab_evt_reg 是在拿到帧数据之后向上回调的,我们后面在接收帧数据的时候会在看到这个函数
void cmr_grab_evt_reg(cmr_handle grab_handle, cmr_evt_cb grab_event_cb) {struct cmr_grab *p_grab;p_grab = (struct cmr_grab *)grab_handle;if (!p_grab)return;pthread_mutex_lock(&p_grab->cb_mutex);p_grab->grab_evt_cb = grab_event_cb;pthread_mutex_unlock(&p_grab->cb_mutex);return;
}
5,一些 cfg
cmr_int cmr_grab_if_cfg(cmr_handle grab_handle, struct sensor_if *sn_if)
cmr_int cmr_grab_sw_3dnr_cfg(cmr_handle grab_handle,struct sprd_img_3dnr_param *threednr_info)
cmr_int cmr_grab_sn_cfg(cmr_handle grab_handle, struct sn_cfg *config)
static cmr_int cmr_grab_cap_cfg_common(cmr_handle grab_handle,struct cap_cfg *config,cmr_u32 channel_id,struct img_data_end *endian)
cmr_int cmr_grab_cap_cfg(cmr_handle grab_handle, struct cap_cfg *config,cmr_u32 *channel_id, struct img_data_end *endian)
cmr_int cmr_grab_3dnr_cfg(cmr_handle grab_handle, cmr_u32 channel_id,cmr_u32 need_3dnr)
cmr_int cmr_grab_longexp_cfg(cmr_handle grab_handle, cmr_u32 need_longexp)
cmr_int cmr_grab_auto_3dnr_cfg(cmr_handle grab_handle,cmr_u32 auto_3dnr_enable)
cmr_int cmr_grab_cap_cfg_lightly(cmr_handle grab_handle, struct cap_cfg *config,cmr_u32 channel_id)
cmr_int cmr_grab_buff_cfg(cmr_handle grab_handle, struct buffer_cfg *buf_cfg)
6,cmr_grab_cap_start 和 cmr_grab_cap_stop
ret = ioctl(p_grab->fd, SPRD_IMG_IO_STREAM_ON, &stream_on); //start
ret = ioctl(p_grab->fd, SPRD_IMG_IO_STREAM_OFF, &stream_on);//stop
他们分别在打开cameraApp 和 退出 CameraApp 的时候被调用的,从如下log时序中可以很清楚的看到。
Line 89953: 07-23 19:57:53.826 8634 8634 I CAM_CameraActivity Drea: onStartTasks start!
Line 92901: 07-23 19:57:55.832 531 8731 D cmr_grab: 1232, cmr_grab_cap_start: ret = 0
Line 102592: 07-23 19:57:59.978 8634 8634 I CAM_CameraActivity Drea: onPauseTasks start!
Line 103137: 07-23 19:58:00.146 531 8731 D cmr_grab: 1274, cmr_grab_cap_stop: ret = 0
7,pause 和 resume
ret = ioctl(p_grab->fd, SPRD_IMG_IO_STREAM_PAUSE, &temp);//pause
ret = ioctl(p_grab->fd, SPRD_IMG_IO_STREAM_RESUME, &temp);//resume
8,cmr_grab_start_capture 和 cmr_grab_stop_capture
根据log,这两个函数是在开启拍照 和 需要的拍照帧数据都拿到后分别调用的
ret = ioctl(p_grab->fd, SPRD_IMG_IO_START_CAPTURE, &capture_param);
ret = ioctl(p_grab->fd, SPRD_IMG_IO_STOP_CAPTURE, &stop);
注:cmr_grab_stop_capture 在退出camera的时候也会被调用一次
9,cmr_grab_cap_resume 和 cmr_grab_cap_pause
常规拍照流程暂未看到这两个函数的调用
10,关键函数:cmr_grab_thread_proc
cmr_grab_thread_proc 就是接受帧数据的函数
static void *cmr_grab_thread_proc(void *data)
10.1 irq_type 含义
CAMERA_IRQ_IMG //1
CAMERA_IRQ_FDRL //9
CAMERA_IRQ_FDRH //10
CAMERA_IRQ_4IN1_DONE //6
CAMERA_IRQ_STATIS //2
CAMERA_IRQ_DONE //3
其中预览和拍照的帧数据都是 CAMERA_IRQ_IMG ,log打印看到也有 2、3这两种类型,但是并没有走后续处理流程,我们目前只关注 CAMERA_IRQ_IMG 类型。
10.2 channel_id 的概念
从参数 data中使用指令 SPRD_IMG_GET_FRM_BUFFER 读数据 到 op 对象中
struct cmr_grab *p_grab;
p_grab = (struct cmr_grab *)data;
cnt = sizeof(struct sprd_img_read_op);
op.cmd = SPRD_IMG_GET_FRM_BUFFER;
op.sensor_id = p_grab->init_param.sensor_id;
if (cnt != read(p_grab->fd, &op, sizeof(struct sprd_img_read_op))) {CMR_LOGE("read failed");break;
}
然后从op对象中可以拿到channel_id的值
op.parm.frame.channel_id
log中看到各类型的channel_id值
preview ---> 1
snapshot ---> 3
callback ---> 2
yuv2 ---> 5
10.3 封装帧数据的值
struct frm_info frame;
frame.height = op.parm.frame.height;
frame.frame_id = op.parm.frame.index;
frame.frame_real_id = op.parm.frame.real_index;
frame.sec = op.parm.frame.sec;
frame.usec = op.parm.frame.usec;
frame.monoboottime = op.parm.frame.monoboottime;
frame.length = op.parm.frame.length;
frame.base = op.parm.frame.frm_base_id;
frame.fmt = cmr_grab_get_img_type(op.parm.frame.img_fmt);
frame.yaddr = op.parm.frame.yaddr;
frame.uaddr = op.parm.frame.uaddr;
frame.vaddr = op.parm.frame.vaddr;
frame.yaddr_vir = op.parm.frame.yaddr_vir;
frame.uaddr_vir = op.parm.frame.uaddr_vir;
frame.vaddr_vir = op.parm.frame.vaddr_vir;
frame.fd = op.parm.frame.mfd;
frame.frame_num = op.parm.frame.frame_id;
frame.zoom_ratio = op.parm.frame.zoom_ratio;
10.4 回调
这里是指针函数 grab_evt_cb,我们在全面说过 cmr_grab_evt_reg 函数,就是给 grab_evt_cb 赋值的。
if (p_grab->grab_evt_cb) {(*p_grab->grab_evt_cb)(evt_id, &frame,(void *)p_grab->init_param.oem_handle);
}
cmr_grab_evt_reg 是在 cmr_oem.c 中调用的,所以cmr_grab在拿到帧数据后会回调到 cmr_oem 中 的 camera_grab_evt_cb 函数。
后面就涉及到 预览帧 和 拍照帧的处理了,分别在 cmr_preview.c 和 cmr_snapshot.c 中,他们的内容都比较多,本篇的重点是cmr_grab.c , 我们会在分别单独写文章介绍cmr_preview.c 和 cmr_snapshot.c。
到这里 cmr_grab.c 就介绍得差不多了,大家只要记住,cmr_grab是oem端最开始拿到帧数据的地方,所以其它算法的流程都基于从这里拿到的帧数据之后。
Camera Hal OEM模块 ---- cmr_grab.c相关推荐
- android mtk camera startpreview,android8.1 mtk camera hal各种操作流程
最近一年,一直在做android上的视频编解码和录相.以及camera hal和系统框架这一块.随着做的慢慢的深入,越发觉得mtk的camera hal这一块,有其独到之处.偏偏网上相关的资料却是极少 ...
- Android Camera 四 Camera HAL 分析
Android Camera 一 源码路径 Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析 Android Camera 三 CameraService 和 Cli ...
- Camera HAL(Camera Preview)
看看Android系统,高通camera hal(camera3)当中camera preview数据是怎么从kernel一层一层传递,最终发给SurfaceView的. 高通的Camera HAL的 ...
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口 6...
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...
- 高通820(msm8996)camera hal源码分析
http://blog.csdn.net/lintwins/article/details/49783917 之前阅读过高通的camera的v4l2的driver,和video codec的drive ...
- Camera HAL Service流程总结
目录 前言 一.HIDL接口 1.CameraProvier 1.setCallback(ICameraProviderCallback callback) 2.getVendorTags 3.get ...
- Camera hal 之 CameraProvider
Camera hal 之 CameraProvider 一.CameraProvider的作用 二.CameraProvider的启动.初始化 一.CameraProvider的作用 cameraPr ...
- Android Camera 五 Camera HAL v1
Android Camera 一 源码路径 Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析 Android Camera 三 CameraService 和 Cli ...
- Android R camera Hal启动(下)
文章目录 前言 代码流程分析 总结 前言 接上一篇Android R camera Hal启动(上)接着写,把谷歌的代码都分析完成,高通/MTK的代码就不贴了. 代码流程分析 上一篇说到getProv ...
最新文章
- c#发送http请求
- halcon知识:共生矩阵
- 对 C++ 历史的个人观点
- iOS核心动画 Core Animation2-CABasicAnimation
- Android中attrs.xml文件的使用详解
- 【COMA】一种将团队回报拆分为独立回报的多智能体算法
- 用普罗米修斯和格拉法纳乐器来刺豪猪
- Taro+react开发(60) 第三方icon使用
- 罗盘时钟编码代码_安全研究 | 利用macOS Dock实现代码的持久化执行
- python3 asyncio_asyncio--python3未来并发编程主流、充满野心的模块
- 乔致庸晚年有白银一千万两,相当于现在多少钱?
- Java - String字符串的部分操作
- python xlrd模块_Python中xlrd模块解析
- pytorch torchvision的版本对应关系 pytorch历史版本
- 【RemoteJoy】PSP图像采集方案
- php arrayaccess什么作用,PHP中的ArrayAccess用法详解
- 002 splitter
- 回忆真是一个痛苦的过程
- 【BZOJ 1006】 [HNOI2008]神奇的国度
- 「WAYZ维智」:全国最具价值的室内外混合定位感知网络 | 百万人学AI评选