Camera模块解析Word文档格式.docx
- 文档编号:16906008
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:21
- 大小:24.77KB
Camera模块解析Word文档格式.docx
《Camera模块解析Word文档格式.docx》由会员分享,可在线阅读,更多相关《Camera模块解析Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
(7)提供给手机芯片内集成的camera模块的PCLK,HCLK,VCLK.(像素同步信号,行同步信号,帧同步信号)。
Sensor通常产出稳定频率的数据图像流,手机芯片可以通过I2C总线接口,修改寄存器,改变帧频率。
也可以改变sensor的输出流的格式,通常采用yuv422格式。
3
CAM简介
CAM就是将Sensor采集过来的数据,转换相应格式,及其他加工,最后存放到内存中。
CAM核心就是个DSP。
这个阶段,dsp可以做很多图像处理的事情。
比如颜色纠正,自动对焦,scaler等。
不同平台会有不同。
由于Sensor的核心也是dsp,对于这些特效工作,一般Sensor中也会提供。
高通平台的Sensor的特效(反色)就可以在Sensor中设置。
由图可知
CAMconsistsofthefollowingelements:
•ImageSignalProcessing(ISP)1
•ColorProcessing
•Imageeffects
•Luminance/ChrominanceSplitter(Y/CSplit)
•Resize(Down/Up-Scalers)
•JPEGEncoder
•YCbCrtoRGBconversionforpreview
•MemoryInterface
•ControlUnit
具体详解,可见ste6715datesheet。
这些模块看似很复杂,对于我们开发者来说,也不复杂。
我们知道它们相应的流程,并且知道每个子模块提供了什么功能。
这些模块的功能可以通过相应模块的寄存器进行相应调整的]。
这同sensor的参数调整的思想是一样的。
硬件提供功能,通过寄存器进行参数调整。
Camera的native层软件接口,在Camera在native层中,提供了/dev/video*的设备节点。
Native层通过打开设备文件,关联上camera,申请一串帧缓冲区,建立循环队列,并把这些内存地址传给内核的camera模块,并等待内核camera的处理结束。
Camera模块一帧处理结束,native层就会返回。
4
LCD显示
LCD的显示,就是将lcd的framebuffer的数据映射到LCD屏上,而我们camera的数据要在屏幕上显示,就只需建立camera帧buffer到framebuffer的映射关系。
可以使用内核的DMA,也可以使用overlay。
通常的preview过程都是在native层以上开个线程,waitingkernel的处理完成,然后push到lcd屏上,如此循环。
(1)软件设计思想
5
V4l2驱动框架:
关联文件:
V4l2-dev.c(src\linux\kernel\linux\drivers\media\video)
Videodev2.h(src\linux\kernel\linux\include\linux)Cam-core分析
V4l2.c(src/linux/modules/v4l2cam)
V4L2是linux的标准接口,提供了众多的标准IOCTL接口,这样不管内核驱动如何改变,风格各异,都可以让应用程序native程序稳定工作。
IOCTL接口标准定义于Videodev2.h,这个文件也会被android系统所引用。
V4L2层的意义在于:
让平台的驱动,通过char字符设备层能够与应用关联起来。
首先对v4l2.c和v4l2-dev.c两个文件的内容做个简单介绍:
(1)V4l2.c文件主要工作:
在模块加载的时候,调用v4l2_init()函数,该函数完成camera_sensor的获取和对video_device设备的创建,初始化和注册。
实际上完成一个video_device设备驱动,最重要的是v4l2_ioctrl()函数的实现,根据android的HAL层传下来的操作类型调用不同的控制函数,而这些控制函数通过调用cameraa_sensor和camIF接口来实现。
(2)V4l2-dev.c文件的主要工作:
完成一个字符设备驱动,并实现了video_device注册的工作。
字符设备驱动中的主要工作是通过调用video_device设备驱动来完成的。
这里请注意:
camera驱动分为三个部分,最后生成cam.ko,v4l2cam.ko和sensor.ko三个模块,v4l2cam.ko依赖于cam.ko和sensor.ko模块,因此,v4l2cam.ko后于cam.ko和sensor.ko模块加载。
下面来分析v4l2框架的工作流程。
(1)v4l2-dev.c
v4l2-dev.c文件中初始化函数申请了v4l2的字符设备号,但是并没有注册和关联具体驱动。
staticint__initvideodev_init(void)
{
dev_tdev=MKDEV(VIDEO_MAJOR,0);
intret;
……
ret=register_chrdev_region(dev,VIDEO_NUM_DEVICES,VIDEO_NAME);
//申请一组设备号
ret=class_register(&
video_class);
//注册一个类设备
}
提供了2个函数供其他具体驱动进行注册
video_register_device_index();
video_register_device();
intvideo_register_device_index(structvideo_device*vdev,inttype,intnr,
intindex)
vdev->
cdev=cdev_alloc();
if(vdev->
cdev==NULL){
ret=-ENOMEM;
gotocleanup;
}
fops->
unlocked_ioctl)
cdev->
ops=&
v4l2_unlocked_fops;
else
v4l2_fops;
owner=vdev->
owner;
ret=cdev_add(vdev->
cdev,MKDEV(VIDEO_MAJOR,vdev->
minor),1);
//注册一个字符设备
memset(&
vdev->
dev,0,sizeof(vdev->
dev));
/*Thememsetaboveclearedthedevice'
sdrvdata,so
putbackthecopywemadeearlier.*/
video_set_drvdata(vdev,priv);
dev.class=&
video_class;
dev.devt=MKDEV(VIDEO_MAJOR,vdev->
minor);
parent)
dev.parent=vdev->
parent;
dev_set_name(&
dev,"
%s%d"
name_base,vdev->
num);
ret=device_register(&
dev);
//注册video_deice设备,将其添加到sysfs文件系统
mutex_lock(&
videodev_lock);
video_device[vdev->
minor]=vdev;
//本地管理的一个video_device数组
mutex_unlock(&
该文件中核心对象为:
staticstructvideo_device*video_device[VIDEO_NUM_DEVICES];
设备文件就是根据index与相应的video_device[index]指针关联。
在videodev_init()初始化函数中,申请了一组设备号,并注册了一个类video_class,在注册视频设备时,首先注册了一个字符设备,然后用相同的设备号注册了一个设备节点。
这里的字符设备是让平台的驱动通过char字符设备层能够与应用关联起来,V4l2框架核心文件为v4l2-dev.c。
v4l2-dev.c文件的核心对象为:
staticstructvideo_device*video_device[VIDEO_NUM_DEVICES],它维护每个注册了的video_device设备,设备文件就是根据index与相应的video_device[index]指针关联。
所以,这个文件的主要工作就是:
字符设备的驱动内容。
字符设备驱动最后还是调用video_device的fops来实现的,这个fops就是v4l2.c中的cam_fops结构体,不过它只实现了打开,关闭,映射和io控制四个函数。
这里要注意的是:
在注册video_device前是通过config_a_device()来初始化video_device的fops的成员的。
(2)V4l2.c:
文件中重要的数据对象:
structacq_device_t{
structvideo_device*vfd;
//视频设备对象指针
#defineNAME_LENGTH16
charname[NAME_LENGTH];
……
*/
structacq_session_cxt_t*streaming;
//打开camera的一个上下文
video_frame_t*stream_vdf[V4L2_MAX_VDF];
/*Hardwaredependantparts*/
/*TheCameraobjectpluggedtoourCAMIF*/
structcamera_sensor*camera;
//sensor对象指针
/*specifictosensor*/
void*camera_priv_data;
};
structacq_session_cxt_t{
//代表一个打开的camera设备
structacq_device_t*dev;
/*handletocontrolsessionofCAMhardwarebloc*/
void*camhdl;
/*datapoolhandle(framemem)*/
void*pool_hdl;
/*jpegbuffers*/
#ifdefCONFIG_V4L2CAM_PMEM
memblock_tblocks[V4L2_MAX_BUF];
#else
structv4l2_bufferbufs[V4L2_MAX_BUF];
#endif
/*CameraPixfmtdefinesthesizeandpixelformatofthesensor.*/
structv4l2_pix_formatCameraPixfmt;
/*CamPixfmtdefinesthesizeandpixelformatattheoutputofCAMbloc*/
structv4l2_pix_formatCamPixfmt;
/*CamPixfmtdefinesthesizeandpixelformatofthumbnailattheoutputofCAMbloc*/
structv4l2_pix_formatCamThumbfmt;
/*videoframeusetopreviewsession*/
video_frame_t*cur_vdf;
video_frame_t*next_vdf;
intcount;
V4l2cam驱动模块的初始化函数流程如下:
intv4l2_init(void)
while
(1){
dev=kzalloc(sizeof(structacq_device_t),GFP_KERNEL);
dev->
camera=v4l2_detect(dev);
//检测并获得camera_sensor设备
/*openthecamblocinterface*/
cam_open(&
hdl);
/*wegotacameraplugged!
*/
/*initialiseprivatefieldsofthesensor,forcmoscoprocessorwetrytofindthecamerapluggedtoit*/
camera_priv_data=dev->
camera->
init();
/*closethecamblocinterface*/
cam_close(hdl);
vfd=video_device_alloc();
//为video_device分配内存
if(config_a_device(dev)){
//初始化video_device设备结构,包括fops成员
unconfig_a_device(dev);
ret=-ENODEV;
gotobail;
if(video_register_device(dev->
vfd,VFL_TYPE_GRABBER,dev->
vfd->
minor)!
=0){
//注册video_device设备
CRITICAL("
Couldn'
tregistervideodriver."
);
is_registered=1;
preview_running=FALSE;
snapshot_running=FALSE;
snapshot_done=FALSE;
/*initcompletion*/
init_completion(&
dev->
complete);
video_set_drvdata(dev->
vfd,dev);
该函数中出现一个config_a_device(dev)函数,这个函数是video_device设备的初始化配置函数,包括对文件操作指针的赋值,这里是一个初始化封装。
先来看看v4l2_detect()函数:
structcamera_sensor*v4l2_detect(structacq_device_t*dev)
structcamera_sensor**Cams=NULL;
structcamera_sensor*cam=NULL;
void*hdl=0;
inti=0;
PROLOG("
"
camera=NULL;
Cams=sensor_get_cameras();
//获取camera_sensor数组
if(Cams){
while(Cams[i]!
=NULL){
cam=Cams[i];
if(!
cam->
isProbed){
cam->
isProbed=1;
if(cam->
detect()==0){
//创建和初始化camera_sensor就在这里,这是sensor驱动部分的内容,后面会有详细的介绍
gotodetect_exit;
i++;
cam=NULL;
detect_exit:
EPILOG("
returncam;
该函数中调用了cam->
detect()函数,这个函数在camera的sensor部分被实现,后面会有详细说明,下面看看如何注册video_device设备的,video_register_device()函数,该函数代码在前面已经列出,这里简单描述:
intvideo_register_device(structvideo_device*vdev,inttype,intnr)
return__video_register_device(vdev,type,nr,1);
staticint__video_register_device(structvideo_device*vdev,inttype,intnr,
intwarn_if_nr_in_use)
ret=cdev_add(vdev->
cdev,MKDEV(VIDEO_MAJOR,vdev->
ret=device_register(&
minor]=vdev;
由驱动框架我们了解到,平台驱动就是初始化video_device结构,然后注册到V4L2框架中。
在V4l2框架中有几个重要内容有必要提出来:
(1)capture_callback()
voidcapture_callback(void*userdata)
structacq_session_cxt_t*acq_cxt=(structacq_session_cxt_t*)userdata;
structacq_device_t*dev;
BUG_ON(!
acq_cxt);
dev=acq_cxt->
dev;
it_frame_nb++;
if(dev->
wait_end_of_frame){
wait_end_of_frame=0;
complete(&
}else{
if(dev->
wait_first_frame){
wait_first_frame=0;
这是一个回调函数,当一帧数据完成时候,中断函数会响应,从而callback函数也会被调用,唤醒comple等待的函数。
此callback函数通过cam_streaming_start函数,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Camera 模块 解析