文章目录

  • 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相关推荐

  1. android mtk camera startpreview,android8.1 mtk camera hal各种操作流程

    最近一年,一直在做android上的视频编解码和录相.以及camera hal和系统框架这一块.随着做的慢慢的深入,越发觉得mtk的camera hal这一块,有其独到之处.偏偏网上相关的资料却是极少 ...

  2. Android Camera 四 Camera HAL 分析

    Android Camera 一 源码路径 Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析 Android Camera 三 CameraService 和 Cli ...

  3. Camera HAL(Camera Preview)

    看看Android系统,高通camera hal(camera3)当中camera preview数据是怎么从kernel一层一层传递,最终发给SurfaceView的. 高通的Camera HAL的 ...

  4. 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口 6...

    在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...

  5. 高通820(msm8996)camera hal源码分析

    http://blog.csdn.net/lintwins/article/details/49783917 之前阅读过高通的camera的v4l2的driver,和video codec的drive ...

  6. Camera HAL Service流程总结

    目录 前言 一.HIDL接口 1.CameraProvier 1.setCallback(ICameraProviderCallback callback) 2.getVendorTags 3.get ...

  7. Camera hal 之 CameraProvider

    Camera hal 之 CameraProvider 一.CameraProvider的作用 二.CameraProvider的启动.初始化 一.CameraProvider的作用 cameraPr ...

  8. Android Camera 五 Camera HAL v1

    Android Camera 一 源码路径 Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析 Android Camera 三 CameraService 和 Cli ...

  9. Android R camera Hal启动(下)

    文章目录 前言 代码流程分析 总结 前言 接上一篇Android R camera Hal启动(上)接着写,把谷歌的代码都分析完成,高通/MTK的代码就不贴了. 代码流程分析 上一篇说到getProv ...

最新文章

  1. c#发送http请求
  2. halcon知识:共生矩阵
  3. 对 C++ 历史的个人观点
  4. iOS核心动画 Core Animation2-CABasicAnimation
  5. Android中attrs.xml文件的使用详解
  6. 【COMA】一种将团队回报拆分为独立回报的多智能体算法
  7. 用普罗米修斯和格拉法纳乐器来刺豪猪
  8. Taro+react开发(60) 第三方icon使用
  9. 罗盘时钟编码代码_安全研究 | 利用macOS Dock实现代码的持久化执行
  10. python3 asyncio_asyncio--python3未来并发编程主流、充满野心的模块
  11. 乔致庸晚年有白银一千万两,相当于现在多少钱?
  12. Java - String字符串的部分操作
  13. python xlrd模块_Python中xlrd模块解析
  14. pytorch torchvision的版本对应关系 pytorch历史版本
  15. 【RemoteJoy】PSP图像采集方案
  16. php arrayaccess什么作用,PHP中的ArrayAccess用法详解
  17. 002 splitter
  18. 回忆真是一个痛苦的过程
  19. 【BZOJ 1006】 [HNOI2008]神奇的国度
  20. 「WAYZ维智」:全国最具价值的室内外混合定位感知网络 | 百万人学AI评选

热门文章

  1. (十)苏世民:我的经验和教训:掌控(1~6)
  2. 《大话物联网(第2版)》赠书活动名单公告
  3. Minicom安装和使用和lte调试方法
  4. Vue验证手机号的同时验证座机号
  5. psd 将分组合并导出png图片
  6. 【OpenGL 学习笔记】第 4 篇:绘制四边形
  7. SEPIC 单端初级电感转换器 稳压器 -- Zeta 转换器
  8. 【报告分享】淘宝直播2021年度报告-淘榜单淘宝直播(附下载)
  9. 【汇正财经】电网设备,享受改革的硕果
  10. 耳鸣头晕是怎么回事?