一、前言
这段时间继续做freescale iMX6Q平台上做项目,项目中用到了一个电视信号输入设备,这玩意就是一个外部电视信号过来我们得通过APP显示出图像和声音来,听上去跟android智能电视一样,猜对了!这就是一个工业用的的视频设备。在开始做之前,我就知道android本身是不支持电视卡这种东西的,但是仔细考虑一下,电视输出分为声音了图像两部分,声音比较简单,就是I2S的输入,然后播放出去。图像部分是难点,但考虑到这玩意跟camera的预览是类似的,可能在现有的camera基础上进行一些小小的修改就可以实现。有了这么一个大概的思路。等硬件来了以后我们开始开始动手,先从难点 图像部分入手, 这篇文章就介绍camera系统kernel部分的代码流程。
二、android camera系统介绍
camera系统做为一个标准的android系统跑不开android的一些基本的结构,如下图是android camera的层次结构
这个结构没有特别的不做过多的描述,这篇文章重点来看硬件和驱动部分。
三、硬件
硬件方面,对于CPU来讲,电视卡就是一个16bit paralle接口的视频输入设备,接口图如下
接口一共20跟线:
PCLK:像素时钟 是像素点同步的时钟信号,也就是每个PCLK对应一个像素点
HSYNC:列同步 在HSYNC有效时段内,sensor所有信号输出属同一行
VSYNC:行同步 在HSYNC有效时段内,sensor所有信号输出属同一帧
DATA_EN:数据使能
data0~data15:16位数据线
再具体的说明大家可以自行百度,这是不做说明。另外电视卡输出信号是UYVY格式的,对于这个格式说明这里贴一个百度百科地址,大家自行研究
http://baike.baidu.com/view/189685.htm
四、驱动
对于kernel来讲camera走的是V4L2的 capture interfac设备,所以我们主要工作就是完成V4L2设备框架,对于每个v4l2 的capture设备都分为两部分,一是master:是视频采集接口的驱动,也就是cpu parallel接口的驱动,一个是slave,是视频设备也就是camera的驱动。这两部分都要由我们来编写或修改来完成。
1.slave设备
我们设备跟CPU接口芯片是GS2971,我们就要写这个片子的驱动,根据GS2971手册来看,它一共支持11种视频格式,v4l2需要我们提供每种视频格式的Timing数据,这个是根据CEA861标准来确定的,可以百度到相关文档,这里拿出一个格式做为说明,
下面这个图是1280x720P50Hz CEA861标准时序图
对于一帧电视图像来说,并不是只有图像本身,在传输过程中是有边界的,就如上图所示其实这帧图像总大小是1980x750,其中1280x720是真正的图像,HSYNC是行同步信号,我们CPU是上升沿触发的,因此从上图可知图像左边界是220+40个像素点,右边界是440个像素点,VSYNC是帧同步和信号,也是上升沿触发,所以上边界是25行,下边界是5行,因此,这组数据是
{
.v4l2_id = V4L2_STD_ALL,
.name = "1280x720P50", //1280x720P50
.raw_width = 1980,
.raw_height = 750,
.act_width = 1280,
.act_height = 720,
.win_top = 20+5,
.win_left = 220+40,
.hs_inv = 0,
.vs_inv = 0,
.is_interlace = 0,
},
数据是根据cpu所需要的写的,右边界和下边界没用所以没有写,其它几种格式,可以按照这个方式写就不多说了。
其它与GS2971片子相关的驱动代码就不多说了,下面看好v4l2设备的注册,主要是给设备提供一个初始状态并且提供v4l2所需的 ioctl,其实也很简单
static struct v4l2_int_slave gs2971_slave = {
.ioctls = gs2971_ioctl_desc,
.num_ioctls = ARRAY_SIZE(gs2971_ioctl_desc),
};
static struct v4l2_int_device gs2971_int_device = {
.module = THIS_MODULE,
.name = "gs2971",
.type = v4l2_int_type_slave,
.u = {
.slave = &gs2971_slave,
},
};
<span style="white-space:pre"> </span>memset(&gs2971_data, 0, sizeof(gs2971_data));
gs2971_data.sen.platform_data = gs2971_tvin_plat;
gs2971_data.sen.mclk = gs2971_tvin_plat->mclk;
gs2971_data.sen.mclk_source = gs2971_tvin_plat->mclk_source;
gs2971_data.sen.csi = gs2971_tvin_plat->csi;
if(gs2971_tvin_plat->sdi_connect){
gs2971_data.irq = gpio_to_irq(gs2971_tvin_plat->sdi_connect);
gs2971_data.sdi_connect = gs2971_tvin_plat->sdi_connect;
}
gs2971_data.sen.plat_device = pdev;
gs2971_data.sen.streamcap.capability = V4L2_MODE_HIGHQUALITY |
V4L2_CAP_TIMEPERFRAME;
gs2971_data.sen.streamcap.capturemode = 0;
gs2971_data.sen.streamcap.timeperframe.denominator = DEFAULT_FPS;<span style="font-family: Arial, Helvetica, sans-serif;">//没秒帧数</span>
gs2971_data.sen.streamcap.timeperframe.numerator = 1;
gs2971_data.std_id = V4L2_STD_ALL;
gs2971_data.sen.pix.width = gs2971_video_fmts[current_video_idx].act_width; //
gs2971_data.sen.pix.height = gs2971_video_fmts[current_video_idx].act_height;
gs2971_data.sen.pix.pixelformat = DEFAULT_PIX_FORMAT; /* YUV422 */
gs2971_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
gs2971_data.sen.on = true;
gpio_sensor_active();
pr_debug(" type is %d (expect %d)\n",
gs2971_int_device.type, v4l2_int_type_slave);
pr_debug(" num ioctls is %d\n",
gs2971_int_device.u.slave->num_ioctls);
/* This function attaches this structure to the /dev/video0 device.
* The pointer in priv points to the mt9v111_data structure here.*/
gs2971_int_device.priv = &gs2971_data;
ret = v4l2_int_device_register(&gs2971_int_device);<span style="white-space:pre"> </span>//<span style="white-space:pre"> </span>注册设备
对于ioctl这里先不说,因为这个要根据master驱动来确定,下面来看master驱动。
2.maser设备
对于master freescale已经有了相关驱动,我们需要一些修改就可以了。驱动代码是
android\kernel_imx\drivers\media\video\mxc\capture\mxc_v4l2_capture.c
我们看probe函数中的设备注册
/* Set up the v4l2 device and register it*/
cam->self->priv = cam;
v4l2_int_device_register(cam->self);
/* register v4l video device */
if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
== -1) {
k

本文介绍了在Android系统中,针对电视信号输入设备如何利用现有的camera框架进行适配。主要探讨了camera系统的层次结构,硬件接口,特别是16bit paralle接口的视频输入设备,以及驱动的V4L2 capture接口。内容涵盖了硬件的信号时钟、数据线,以及驱动的master和slave设备部分,包括GS2971驱动的编写和V4l2设备的注册。
最低0.47元/天 解锁文章
1186

被折叠的 条评论
为什么被折叠?



