关键词:android  camera CMM 模组 camera参数  CAMIF   V4L2  
平台信息:
内核:
linux
系统:android

平台:S5PV310(samsung exynos 4210)

作者:xubin341719(欢迎转载,请注明作者)

android camera(一):camera模组CMM介绍

android camera(二):摄像头工作原理、s5PV310 摄像头接口(CAMIF)

android camera(三):camera V4L2 FIMC

android camera(四):camera 驱动 GT2005

下载:常用摄像头规格书(个别有android驱动程序)  :bf3703 30W、gc0308 30W、ov7670、gt2005 200W、gt2015 200W、NT99250 200W、s5k5ba 200W、s5k4ba

前面两篇说的有点多了,不过多了解点东西也挺好的,遇到问题时可以有更多的思路,真正驱动是从这一块开始。一般BSP的camera都是完好的,我们只用关心驱动这些就可以了。

1. V4L2

1)简介

在Linux中,摄像头方面的标准化程度比较高,这个标准就是V4L2驱动程序,这也是业界比较公认的方式。

V4L全称是Video for Linux,是Linux内核中标准的关于视频驱动程序,目前使用比较多的版本是Video for Linux 2,简称V4L2。它为Linux下的视频驱动提供了统一的接口,使得应用程序可以使用统一的API操作不同的视频设备。从内核空间到用户空间,主要的数据流和控制类均由V4L2驱动程序的框架来定义。

V4L2驱动程序一般只提供Video数据的获得,而如何实现视频预览,如何向上层发送数据,如何把纯视频流和取景器、视频录制等实际业务组织起来,都是camera的硬件抽象层需要负责的工作。

V4L2驱动核心实现为如下文件:drivers/media/video/v4l2-dev.c。

V4l2-dev.h中定义的video_device是V4L2驱动程序的核心数据结构,它为具体的摄像头sensor驱动提供了接口调用。

V4l2的采集过程(应用程序):

1)     打开设备,获得文件描述符;

2)     设置图片格式;

3)     分配缓冲区;

4)     启动采集过程,读取数据;

5)     停止采集,关闭设备。

2)数据结构

V4L2的主要数据结构是video_device,定义在v4l2_dev.h中:

struct video_device
{
/* device ops */
const struct v4l2_file_operations *fops; /*接口函数指针*/ /* sysfs */
struct device dev; /* v4l 设备结构 */
struct cdev *cdev; /* 字符设备结构*/ /* Set either parent or v4l2_dev if your driver uses v4l2_device */
struct device *parent; /* 设备父指针 */
struct v4l2_device *v4l2_dev; /* v4l2设备指针*/ /* device info */
char name[]; /*设备名称*/
int vfl_type;
/* 'minor' is set to -1 if the registration failed */
int minor; /*次设备号*/
u16 num;
/* use bitops to set/clear/test flags */
unsigned long flags;
/* attribute to differentiate multiple indices on one physical device */
int index; /* V4L2 file handles */
spinlock_t fh_lock; /* Lock for all v4l2_fhs */
struct list_head fh_list; /* List of struct v4l2_fh */ int debug; /* debug 级别*/ /* Video 标准变量 */
v4l2_std_id tvnorms; /* Supported tv norms */
v4l2_std_id current_norm; /* Current tvnorm */ /* 回调函数 */
void (*release)(struct video_device *vdev); /* ioctl 回调函数 */
const struct v4l2_ioctl_ops *ioctl_ops;
};

int video_register_device(struct video_device *vdev, int type, int nr);

static int v4l2_ioctl(struct inode *inode, struct file *filp,       unsigned int cmd, unsigned long arg);

2.  FIMC                     

1)简介

FIMC这个模块不仅仅是一个摄像头的控制接口,它还承担着V4L2的output功能和overlay的功能。

FIMC的驱动在内核中的位置:drivers/media/video/samsung/fimc

它包含下边的文件:

fimc_regs.c
      fimc_capture.c
      fimc_dev.c
      fimc_output.c
      fimc_overlay.c
      fimc_v4l2.c

它们的组织关系如下:

可以看到,FIMC的驱动实现了v4l2所有的接口,可以分为v4l2-input设备接口,v4l2-output设备接口以及v4l2-overlay设备接口。这里我们主要关注v4l2-input设备接口,因为摄像头属于视频输入设备。

fimc_v4l2.c里面注册了很多的回调函数,都是用于实现v4l2的标准接口的,但是这些回调函数基本上都不是在fimc_v4l2.c里面实现的,而是有相应的.c分别去实现。比如:

  v4l2-input设备的操作实现:fimc_capture.c
      v4l2-output设备的操作实现: fimc_output.c
      v4l2-overlay设备的操作实现: fimc_overlay.c

这些代码其实都是和具体硬件操作无关的,这个驱动把所有操作硬件寄存器的代码都写到一个文件里面了,就是fimc40_regs.c。这样把硬件相关的代码和硬件无关的代码分开来实现是非常好的方式,可以最大限度的实现代码复用。

 2) 数据结构 

FIMC的主要数据结构fimc_control,定义在fimc.h中:

struct fimc_control {
int id; /* 控制器 id */
char name[];
atomic_t in_use;
void __iomem *regs; /* 寄存器 i/o */
struct clk *clk; /* interface clock */
struct regulator *regulator; /* pd regulator */
struct fimc_meminfo mem; /* for reserved mem */ /* kernel helpers */
struct mutex lock; /* controller lock */
struct mutex alloc_lock;
struct mutex v4l2_lock;
wait_queue_head_t wq;
struct device *dev;
int irq; /* v4l2 related */
struct video_device *vd;
struct v4l2_device v4l2_dev; /* fimc specific */
struct fimc_limit *limit; /* H/W limitation */
struct s3c_platform_camera *cam; /* activated camera */
struct fimc_capinfo *cap; /* capture dev info */
struct fimc_outinfo *out; /* output dev info */
struct fimc_fbinfo fb; /* fimd info */
struct fimc_scaler sc; /* scaler info */
struct fimc_effect fe; /* fimc effect info */ enum fimc_status status;
enum fimc_log log; u32 ctx_busy[FIMC_MAX_CTXS];
};

因为FIMC一共有三套一样的控制器(fimc0, fimc1, fimc2),所以驱动里使用了一个数组来描述:

struct video_device fimc_video_device[FIMC_DEVICES] = {
[] = {
.fops = &fimc_fops,
.ioctl_ops = &fimc_v4l2_ops,
.release = fimc_vdev_release,
},
[] = {
.fops = &fimc_fops,
.ioctl_ops = &fimc_v4l2_ops,
.release = fimc_vdev_release,
},
[] = {
.fops = &fimc_fops,
.ioctl_ops = &fimc_v4l2_ops,
.release = fimc_vdev_release,
},
};

fb_ops结构体是针对v4l2设备的基本操作,定义如下:

static const struct v4l2_file_operations fimc_fops = {
.owner = THIS_MODULE,
.open = fimc_open,
.release = fimc_release,
.ioctl = video_ioctl2,
.read = fimc_read,
.write = fimc_write,
.mmap = fimc_mmap,
.poll = fimc_poll,
};

3)FIMC初始设置

在S5PV210中,FIMC初始设置代码在 /drivers/ arch/arm/mach-s5pv210/mach-smdkv310.c中:

static struct s3c_platform_fimc fimc_plat = {
.srclk_name = "mout_mpll",
.clk_name = "sclk_fimc",
.lclk_name = "sclk_fimc_lclk",
.clk_rate = ,
.default_cam = CAMERA_CSI_C,
.camera = {
&mt9p111,//5M back cam
&s5k6aafx,///1.3M front cam
},
.hw_ver = 0x43,
};

对于GPIO的配置代码在 /drivers/ arch/arm/mach-s5pv210/setup-fimc0.c中:

FIMC的主要回调函数如下,实现在fimc_v4l2.c中:

onst struct v4l2_ioctl_ops fimc_v4l2_ops = {
.vidioc_querycap = fimc_querycap,
.vidioc_reqbufs = fimc_reqbufs,
.vidioc_querybuf = fimc_querybuf,
.vidioc_g_ctrl = fimc_g_ctrl,
.vidioc_s_ctrl = fimc_s_ctrl,
.vidioc_s_ext_ctrls = fimc_s_ext_ctrls,
.vidioc_cropcap = fimc_cropcap,
.vidioc_g_crop = fimc_g_crop,
.vidioc_s_crop = fimc_s_crop,
.vidioc_streamon = fimc_streamon,
.vidioc_streamoff = fimc_streamoff,
.vidioc_qbuf = fimc_qbuf,
.vidioc_dqbuf = fimc_dqbuf,
.vidioc_enum_fmt_vid_cap = fimc_enum_fmt_vid_capture,
.vidioc_g_fmt_vid_cap = fimc_g_fmt_vid_capture,
.vidioc_s_fmt_vid_cap = fimc_s_fmt_vid_capture,
.vidioc_try_fmt_vid_cap = fimc_try_fmt_vid_capture,
.vidioc_enum_input = fimc_enum_input,
.vidioc_g_input = fimc_g_input,
.vidioc_s_input = fimc_s_input,
.vidioc_g_parm = fimc_g_parm,
.vidioc_s_parm = fimc_s_parm,
.vidioc_queryctrl = fimc_queryctrl,
.vidioc_querymenu = fimc_querymenu,
.vidioc_g_fmt_vid_out = fimc_g_fmt_vid_out,
.vidioc_s_fmt_vid_out = fimc_s_fmt_vid_out,
.vidioc_try_fmt_vid_out = fimc_try_fmt_vid_out,
.vidioc_g_fbuf = fimc_g_fbuf,
.vidioc_s_fbuf = fimc_s_fbuf,
.vidioc_try_fmt_vid_overlay = fimc_try_fmt_overlay,
.vidioc_g_fmt_vid_overlay = fimc_g_fmt_vid_overlay,
.vidioc_s_fmt_vid_overlay = fimc_s_fmt_vid_overlay,
};

对于寄存器的操作,实现都在fimc_regs.c文件中,如

【转】android camera(三):camera V4L2 FIMC的更多相关文章

  1. sc7731 Android 5.1 Camera 学习之一Camera 两个对象

    众所周知,在Android中Camera采用了C/S架构,其中Camera server 与 Camera client之间通过Android Binder IPC机制进行通信.在Camera实现的框 ...

  2. 【转】[Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现

    参考http://stackoverflow.com/questions/18460647/android-setfocusarea-and-auto-focus http://blog.csdn.n ...

  3. Android 自带 camera 详解

    在本文中 需要考虑的问题 概述 Manifest声明 使用内置的摄像头应用程序 捕获图像的intent 捕获视频的intent 接收摄像头intent的结果 创建摄像头应用程序 检测摄像头硬件 访问摄 ...

  4. Android中利用Camera与Matrix实现3D效果详解

    本文行文目录: 一.Camera与Matrix初步认识 二.Camera与Matrix旋转效果拆分介绍 三.Camera与Matrix实现立体3D切换效果 [csdn地址:http://blog.cs ...

  5. [Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现

    写在前面 最近在从零开始写一个移动端的AR系统,坑实在是太多了!!!整个项目使用了OpenCV第三方库,但对于摄像机来说,和原生Camera的方法基本相同. 实现 以OpenCV的JavaCamera ...

  6. Android 5.1 Camera 架构学习之Camera初始化

    Android Camera 采用C/S架构,client 与server两个独立的线程之间(CameraService)使用Binder通信. 一 CameraService的注册. 1.手机开机后 ...

  7. Android开发技巧——Camera拍照功能

    本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结.由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2. 文 ...

  8. Android 自定义属性动画&Camera动画

      摘要: Android 自定义属性动画&Camera动画 1.相关知识点 对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了 Animati ...

  9. Cesium案例解析(三)——Camera相机

    目录 1. 概述 2. 实例 2.1. Camera.html 2.2. Camera.js 2.2.1. 飞行至某一点 2.2.2. 飞行至某区域 2.2.3. 两地之间飞行 2.2.4. 设置视图 ...

随机推荐

  1. Ubuntu Eclipse的Tomcat小问题:不能输入server name,不能启动tomcat

    Ubuntu的Eclipse上安装Tomcat环境,这是让人烦啊,万幸还是终于解决了. Eclipse上Tomcat的搭建: 1.点击Eclipse上的菜单:Windows - Preference, ...

  2. POJ 2010 Moo University - Financial Aid 优先队列

    题意:给你c头牛,并给出每头牛的分数和花费,要求你找出其中n(n为奇数)头牛,并使这n头牛的分数的中位数尽可能大,同时这n头牛的总花费不能超过f,否则输出-1. 思路:首先对n头牛按分数进行排序,然后 ...

  3. Unity 屏幕适配小脚本

    屏幕适配是可以通过代码实现的,相信给你时间就一定能写出来. 我们公司貌似没有分辨率适配框架通常对应小屏幕的苹果4要额外设置下等等就完了! 屏幕适配框架实现思路:  通过代码获取当前的分辨率 –> ...

  4. 将string 转int

    /** * @param {string} str * @return {number} */ var myAtoi = function(str) { str = str.replace(/^(\s ...

  5. Android开发之去掉标题栏的三种方法,推荐第三种

    Android:去掉标题栏的三种方法和全屏的三种方法 第一种:一般入门的时候常常使用的一种方法 onCreate函数中增加下面代码: requestWindowFeature(Window.FEATU ...

  6. 用函数式的 Swift 实现图片转字符画的功能

    今天整理 Pocket 中待看的文章,看到这篇<Creating ASCII art in functional Swift>,讲解如何用 Swift 将图片转成 ASCII 字符.具体原 ...

  7. linux ssh-keygen

    用ssh client 客户端 远程登录服务器,避免每次都得输入密码: 解决方法: ssh-keygen  复制 id_rsa.pub 中的内容 到 远程连接的服务器的~/.ssh/authorize ...

  8. C# 文件操作(一)

    1.说明: 写入文件内容,如果文件中有内容,则进行追加,目录是程序集下的目录 public static void WriteLog(string value) { try { //目录是程序集下的D ...

  9. box-shadow讲解1

    谈谈box-shadow的具体使用方法 语法: E {box-shadow: <length> <length> <length>?<length>?| ...

  10. hdu1215七夕节

    Problem Description 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" ...