MTK6577+Android之Camera驱动

MTK6577+Android之Camera驱动

《MTK安卓平台的Camera效果在线调试》



1.     Camera拍照相关概念

 

1.1  ISP

 

isp——(Image Signal Processor)——影视处理

 

无论数码相机、摄像机或者摄像手机,其影像数据从前端感应后,皆须经过ASP(Analog Signal Processing)、ADC(Analog-Digital Converter)、前期影像处理(Pre-ISP)与后端影像处理(Post-ISP)四个阶段后,影像数据才能最终呈现于终端设备上

 

1.2  720p

720P是美国电影电视工程师协会(SMPTE)制定的高等级高清数字电视的格式标准,有效显示格式为:1280×720.SMPTE(美国电影电视工程协会)将数字高清信号数字电视扫描线的不同分为1080P、1080I、720P(i是interlace,隔行的意思,p是Progressive,逐行的意思)。720P是一种在逐行扫描下达到1280×720的分辨率的显示格式。是数字电影成像技术和计算机技术的融合。

 

分辨率为1280×720p/60Hz,行频为45kHz

 

 

2.     MTK6577Camera控制器部分

 

2.1  camera控制器概述

MT6577 camera可接受RAM和SOC传感器处理之后的图像数据(sensor image data),并输出YUV数据给MDP(什么的简称)。Camera控制器可同时连接2个并行SOC传感器,它提供像素缺陷补偿(bad pixel compensation)、去马赛克(demosaic)、边缘曾强(edge enhancement)、标准色自适应(preference color adaptation)、空间和暂时噪声消除(spatial and temporal noise reduction)这些特征,用于图像处理。

 

2.2  camera特征

 

MT6577内部集成的ISP,包含了一个功能强大的图像信号处理器,用于连接各种各样的图像传感器模组,这个处理器由时序产生单元(timing generated unit: TG)、镜头/传感器补偿(lens/sensor compensation)单元和图像处理单元。

 

支持的特征如下:(1)   抓图分辨率达8M像素(image capture resolution)。

                           (2)   录像分辨率达720p(video recording resolution)。

            (3)   原始图像数据转储帧率8M@15(raw dump frame rate)。

     (4)   曝光抓图率8M@7(burst capture rate)。(5)   图像处理

低像素补偿(poor pix compensation)、镜头阴影补偿(lens shading compensation)、去马赛克(demosaic)、色彩削波(color clipping)、局部对比度增强(local contrast enhancement)、伽玛校正(gamma correction)、边缘曾强(edge enhancement)、噪声消除(noise reduction)、标准色自适应(preference color adaptation)、空间和暂时噪声消除(spatial and temporal noise reduction)。

 

(6)   3A统计和校正(statistics and correction)

(7)   闪烁检测(flicker detection)。

 

2.3  camera框图


TG只配合主图像传感器(master type image sensor),也就是说主图像传感器应发送垂直和水平信号给TG。TG通过内部自动同步 (internal auto synchronization)或外部像素时钟同步来提供传感器所需要的数据时钟和接收传感器Bayer模式原始数据(Bayer pattern raw data)。TG的主要目的是为主图像传感器创建数据时钟和接收垂直/水平同步信号与sensor数据,然后产生Bayer数据的捕获区域(grabbed area of Bayer data)或是YUV422/RGB565数据给镜头/传感器补偿(lens/sensor compensation)单元。

 

在Bayer原始数据输入模式,镜头/传感器补偿(lens/sensor compensation)单元产生补偿的原始数据给色彩处理单元(color process unit);在YUV422/RGB565 输入模式,这步被忽略。

 

色彩处理单元接受来之镜头/传感器补偿(lens/sensor compensation)单元产生补偿的原始数据或是YUV422/RGB565数据。ISP的输出的是很容易被压缩引擎(compress engine,JPEG编码器和MPEG4编码器)编码的YCbCr888数据格式,它是其他数据格式转化的基本数据域(比如R/G/B domain)(it can be the basic data domain of otherdata format translation such as the R/G/B domain)。ISP是流水线式(pipelined),在处理阶段ISP硬件能够为后面的AE/AF/AWB计算提取有意义的信息,这些信息被临时保存在ISP寄存器或是内存中,并且能够被MCU读取出来。

 

下面给出一些性能参数:


3.     原理图设计

 

MT6577支持两路camera接口,一路是MIPI接口,一路是并行接口,这里我们采用的是并行接口,下面给出MT6577 CAM并行接口定义:


Camera sensor连接座如下:


(1)  OV5640输出的数据格式

《Y1MT6577 design notice V0.1.pdf》文档给出这样的说明:

Sensor outputformat is RAM8/YUV/JPEG,connect sensor output to CMDAT[0:7] or CMDAT[2:9]

Sensor outputformat is RAM10,connect sensor output to CMDAT[0:9]

而我们采用摄像头模组的驱动IC为OV5640(500万像素: active array size: 2592 x 1944) Sensor :outputformats: 8-/10-bit RGB RAW output,这是由OV5640寄存器0x4745决定的。原则就是:首先看硬件上采用的是8根数据线还是10根数据线,然后初始化参数-也就是寄存器设定也可以设定是8位或10位。如下图:


(2)  OV5640IIC地址

 

IIC 8bit写地址为0x78,读地址为0x79,查询Sensor规格书可以看到


(2)  OV5640IIC地址

 

IIC 8bit写地址为0x78,读地址为0x79,查询Sensor规格书可以看到


图7

IIC 8bit地址最后一位为0时是写地址,为1时是读地址。这属于IIC通讯规则

 

 

 

4.     驱动实现

 

 

4.1  相关代码

(1)  CameraSensor驱动相关文件

\mediatek\custom\common\kernel\imgsensor\ov5642_yuv

 

(2)  SensorID和一些枚举类型的定义

\mediatek\custom\common\kernel\imgsensor\inc

kd_imgsensor.h---------SensorID

kd_imgsensor_define.h--------------一些枚举类型的定义

 

(3)  Sensor供电

\mediatek\custom\common\kernel\camera\camera

kd_camera_hw.c和kd_camera_hw.h

 

(4)  KernelSpace的SensorList,imgsensor模块注册

\mediatek\custom\common\kernel\imgsensor\src

kd_sensorlist.c和kd_sensorlist.h-----------camera模块加载

 

(5)  UserSpace的SensorList,向用户空间提供支持的SensorList

\mediatek\custom\common\hal\imgsensor\src\sensorlist.cpp

提供给用户空间的SensorList

 

 

(6)  Sensor效果调整的接口

\mediatek\custom\common\hal\imgsensor\ov5642_yuv

 

 

4.2  针对OV5640的修改

 

4.2.1       mediatek\config\hsimobile77_ics2\ProjectConfig.mk

 

CUSTOM_KERNEL_IMGSENSOR=mt9p017_rawgc0329_yuv

mt9p017_raw表示后置摄像头(也就是主摄像头),mt9p017是摄像头sensor驱动IC,raw是sensor一种输出的数据格式,是CCD或CMOS在将光信号转换为电信号时的电平高低的原始记录,单纯地没有将没有进行任何处理的图像数据,即摄像元件直接得到的电信号进行数字化处理而得到的。

 

gc0329_yuv是前置摄像头,yuvsensor一种输出的数据格式,支持YUV/RGB格式的模组,一般会带有ISP(image single processor),经过A/D转换过的原始数据经过ISP处理生成YUV标准格式传到BB。

 

我们采用的OV5640就带有ISP,输出YUV格式

 

(1)  把mt9p017_raw 改为ov5640_yuv,去掉gc0329_yuv因为我们的产品没有后置摄像头

(2)  去掉类似CUSTOM_KERNEL_LENS后面的dummy_lens因为没有后置摄像头

 

修改之后的HAL层的配置:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CUSTOM_HAL_IMGSENSOR=ov5640_yuv  
  2. CUSTOM_HAL_LENS=fm50afdummy_lens  
  3. CUSTOM_HAL_MAIN_BACKUP_IMGSENSOR=  
  4. CUSTOM_HAL_MAIN_BACKUP_LENS=  
  5. CUSTOM_HAL_MAIN_IMGSENSOR=ov5640_yuv  
  6. CUSTOM_HAL_MAIN_LENS=fm50af  
  7. CUSTOM_HAL_MATV=  
  8. CUSTOM_HAL_MSENSORLIB=mmc328xakm8975 ami304 yamaha530 mag3110 akmd8963  
  9. CUSTOM_HAL_SENSORS=sensor  
  10. CUSTOM_HAL_SUB_BACKUP_IMGSENSOR=  
  11. CUSTOM_HAL_SUB_BACKUP_LENS=  
  12. CUSTOM_HAL_SUB_IMGSENSOR=  
  13. CUSTOM_HAL_SUB_LENS=dummy_lens  

修改之后的kernel层的配置:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CUSTOM_KERNEL_IMGSENSOR=ov5640_yuv  
  2. CUSTOM_KERNEL_JOGBALL=  
  3. CUSTOM_KERNEL_KPD=kpd  
  4. CUSTOM_KERNEL_LCM=ili9806e  
  5. CUSTOM_KERNEL_LEDS=mt65xx  
  6. CUSTOM_KERNEL_LENS=fm50afdummy_lens  
  7. CUSTOM_KERNEL_MAGNETOMETER=akm8975  
  8. CUSTOM_KERNEL_MAIN_BACKUP_IMGSENSOR=  
  9. CUSTOM_KERNEL_MAIN_BACKUP_LENS=  
  10. CUSTOM_KERNEL_MAIN_IMGSENSOR=ov5640_yuv  
  11. CUSTOM_KERNEL_MAIN_LENS=fm50af  
  12. CUSTOM_KERNEL_MATV=  
  13. CUSTOM_KERNEL_OFN=  
  14. CUSTOM_KERNEL_RTC=rtc  
  15. CUSTOM_KERNEL_SOUND=amp_6329pmic_2in1_spk  
  16. CUSTOM_KERNEL_SUB_BACKUP_IMGSENSOR=  
  17. CUSTOM_KERNEL_SUB_BACKUP_LENS=  
  18. CUSTOM_KERNEL_SUB_IMGSENSOR=  
  19. CUSTOM_KERNEL_SUB_LENS=dummy_lens  


虽然我们没有后置摄像头,但不能去掉dummy_lens,我尝试过去掉之后用./mk r dr编译会提示下面的错误:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld:out/target/product/hsimobile77_ics2/obj/SHARED_LIBRARIES/libcameracustom_intermediates/common/hal/lens/lenslist.o:in function global constructors keyed tolenslist.cpp:mediatek/source/external/mhal/src/custom/common/hal/lens/lenslist.cpp:82:error: undefined reference to 'pDummy_getDefaultData'  
  2. make[3]: ***[out/target/product/hsimobile77_ics2/obj/SHARED_LIBRARIES/libcameracustom_intermediates/LINKED/libcameracustom.so]Error 1  


4.2.2       mediatek\custom\common\kernel\imgsensor----------kernel层

 

(1)  创建ov5640_yuv并建立需要的文件

 

创建文件夹ov5640_yuv,把sensor IC厂家提供的ov5640yuv_Sensor.c放到此目录下。另外拷贝ov5642yuv_Sensor.h、ov5642yuv_Camera_Sensor_para.h、ov5642yuv_CameraCustomized.h拷贝过来改为ov5640yuv_Sensor.h等。

 

编译发现mediatek\custom\common\kernel\imgsensor\ov5640_yuv\ov5640yuv_Sensor.c文件用到的OV5640_FULL_PERIOD_PIXEL_NUMS_HTS、OV5640_FULL_PERIOD_LINE_NUMS_VTS、OV5640_PV_PERIOD_PIXEL_NUMS_HTS和OV5640_PV_PERIOD_LINE_NUMS_VTS没有定义,但ov5642yuv_Sensor.c是没有这几个宏定义,我暂时定义如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //kandi add startat 2014.11.29  
  2. #defineOV5640_FULL_PERIOD_PIXEL_NUMS_HTS  OV5640_FULL_PERIOD_PIXEL_NUMS  
  3. #define  OV5640_FULL_PERIOD_LINE_NUMS_VTS   OV5640_FULL_PERIOD_LINE_NUMS  
  4.    
  5. #defineOV5640_PV_PERIOD_PIXEL_NUMS_HTS  OV5640_PV_PERIOD_PIXEL_NUMS  
  6. #define  OV5640_PV_PERIOD_LINE_NUMS_VTS   OV5640_PV_PERIOD_LINE_NUMS  

这是参考ov5642的相关定义来定义的。

 

(2)  在支持的sensor列表中增加目标sensor

 

mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.h

在数组增加OV5640的内容,如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ACDK_KD_SENSOR_INIT_FUNCTION_STRUCTkdSensorList[MAX_NUM_OF_SUPPORT_SENSOR+1] =  
  2. {  
  3.        ………….  
  4.        #if defined(OV5640_YUV)  
  5. {OV5640_SENSOR_ID,SENSOR_DRVNAME_OV5640_YUV, OV5640_YUV_SensorInit},  
  6. #endif  
  7. …………….  
  8. }  

也增加UINT32 OV5640_YUV_SensorInit(PSENSOR_FUNCTION_STRUCT*pfFunc);

mediatek\custom\common\kernel\imgsensor\inc\kd_imgsensor.h

 

(3)  增加sensor ID和字符串的定义

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #defineOV5640_SENSOR_ID            0x5640  
  2. #defineSENSOR_DRVNAME_OV5640_YUV  "ov5640yuv"  

4.2.3       mediatek\custom\common\hal\imgsensor---------------HAL层

 

(1)  创建ov5640_yuv文件夹

但这些文件夹下该有哪些文件,有需要哪些内容了,首先我对比了

ov3640_yuv和ov5642_yuv文件夹,只有cfg_ftbl_ov5642_yuv.h有差别:

 

图8

这里主要是不同驱动IC支持的分辨率不同,以及设置默认的分辨率。


图9

此文件下有两个这样的地方不同,这里是指自动对焦模式。

 

因为我们的OV5640和OV5642非常接近,所以就直接把OV5642的目录复制过来修改为OV5640即可。

 

所以把mediatek\custom\common\kernel\imgsensor\ov5642_yuv拷贝到imgsensor目录下,改为ov5640_yuv

 

(2)  在支持的sensor列表中增加目标sensor

 

\src\ sensorlist.cpp

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MSDK_SENSOR_INIT_FUNCTION_STRUCTSensorList[] =  
  2. {  
  3. ………..  
  4. #ifdefined(OV5640_YUV)  
  5.     YUV_INFO(OV5640_SENSOR_ID,SENSOR_DRVNAME_OV5640_YUV, NULL),  
  6. #endif  
  7. …………  
  8. }  

注意:在 kd_SensorList.h 和 SensorList.cpp 里面添加驱动的时候要注意,Sensor 添加的位置要一样。否则驱动会跑乱,轻则 ISP 参数不对,重则 Sensor 无法启动。

 

 

4.3  拍照图片尺寸设置

 

mediatek\custom\common\hal\imgsensor\ov5640_yuv\cfg_ftbl_ov5640_yuv.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Capture Size  
  2.    CONFIG_FEATURE_SI(FID_CAP_SIZE,  
  3.        BY_DEFAULT(CAPTURE_SIZE_2560_1920),  
  4.        CAPTURE_SIZE_1280_960,  CAPTURE_SIZE_1600_1200,  
  5.        CAPTURE_SIZE_2048_1536,CAPTURE_SIZE_2560_1920  
  6.    )  

4.4  Camera物理角度旋转

Cfg_setting_imgsensor.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /******************************************************************************* 
  2. * Image SensorOrientation 
  3. *******************************************************************************/  
  4. SensorOrientation_Tconst&  
  5. getSensorOrientation()  
  6. {  
  7.     static SensorOrientation_T const inst = {  
  8.         u4Degree_0  : 0,//270,//180,//90,   // main sensor in degree (0, 90, 180, 270),kandi change from 90 to 180  
  9.         u4Degree_1  : 0,   //  sub  sensor in degree (0, 90, 180, 270)  
  10.     };  
  11.     return inst;  
  12. }  

这几种都试过了,但都不行,预览和实际的都是成某种镜像关系。这是平台是提供旋转的功能。这个配置好了之后,如果方向不正确,可以通过驱动中的方向调整函数进行调整,如下: static void XXXXXSetMirror(kal_uint16ImageMirror)

参考:http://blog.csdn.net/loongembedded/article/details/41679977

 

 

 

看了OV5640的数据手册,寄存器0x3820和0x3821是用于控制图像发射(mirror)和翻转(flip)的,在u4Degree_0=270情况下,OV5640YUVPreview()调用OV5640YUV_Set_Mirror_Flip (IMAGE_V_MIRROR),预览和拍照后的预览都是OK,但拍好的照片在电脑上打开的时候发现是顺时针翻转了90度。

http://bbs.csdn.net/topics/390837150

 

可是我在OV5640YUV_Sensor_Init()调用OV5640YUV_Set_Mirror_Flip(IMAGE_V_MIRROR)却问题依旧,很奇怪。

 

mediatek\custom\common\hal\imgsensor\ov5640_yuv\cfg_ftbl_ov5640_yuv.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.     // Capture Size 
  3.     CONFIG_FEATURE_SI(FID_CAP_SIZE, 
  4.         BY_DEFAULT(CAPTURE_SIZE_2560_1920), 
  5.         CAPTURE_SIZE_1280_960,  CAPTURE_SIZE_1600_1200, 
  6.         CAPTURE_SIZE_2048_1536,CAPTURE_SIZE_2560_1920 
  7.     ) 
  8.     */  
  9.      // Capture Size  
  10.     CONFIG_FEATURE_SI(FID_CAP_SIZE,  
  11.         BY_DEFAULT(CAPTURE_SIZE_1920_2560),  
  12.         CAPTURE_SIZE_960_1280,  CAPTURE_SIZE_1200_1600,  
  13.         CAPTURE_SIZE_1536_2048,CAPTURE_SIZE_1920_2560  
  14. )  


 

我试过做上面的修改,但打开摄像头的时候,提示”Unfortunately, Camera has stopped”

 

 

 

参考链接:

MTKAndroid Driver:camera

http://blog.csdn.net/cbk861110/article/details/17437283

 

 

MTK cameraimage sensor driver

http://blog.csdn.net/sunweizhong1024/article/details/8497790

 

MTK平台的ISP架构问题

http://bbs.52rd.com/forum.php?mod=viewthread&tid=272727

 

OV5640 YUV的自动对焦功能为何没有开启

http://www.16rd.com/thread-10480-1-1.html

 

MTK Android Driver知识大全

http://blog.csdn.net/cbk861110/article/details/40931835

 

mtk camera移植步骤

http://blog.csdn.net/vasvas/article/details/39250473

 

关于 前置摄像头安装0度或者180度

http://blog.csdn.net/kkkvvv123/article/details/8809823

 

Camera 涉及的文件70

http://3y.uu456.com/bp-6dq1aascss2707221q2ef7es-1.html

 

OV5640全景模式预览倒180度,拍照正常的问题

http://blog.csdn.net/guoguo295/article/details/21245815

猜你喜欢

转载自blog.csdn.net/ds1130071727/article/details/80223299