4 n4 K% X6 t! e5 f: _
图1
6 I& i* j7 m% z V9 Y* y1. Camera拍照相关概念 1.1 ISP
, L8 x3 ?9 k2 \9 Qisp——(Image Signal Processor)——影视处理
9 i. I4 J( n1 T6 c+ A' R' [& I# @无论数码相机、摄像机或者摄像手机,其影像数据从前端感应后,皆须经过ASP(Analog Signal Processing)、ADC(Analog-Digital Converter)、前期影像处理(Pre-ISP)与后端影像处理(Post-ISP)四个阶段后,影像数据才能最终呈现于终端设备上
3 z8 F! C! k8 i. s/ p1.2 720p 720P是美国电影电视工程师协会(SMPTE)制定的高等级高清数字电视的格式标准,有效显示格式为:1280×720.SMPTE(美国电影电视工程协会)将数字高清信号数字电视扫描线的不同分为1080P、1080I、720P(i是interlace,隔行的意思,p是Progressive,逐行的意思)。720P是一种在逐行扫描下达到1280×720的分辨率的显示格式。是数字电影成像技术和计算机技术的融合。
' q% `- J# V+ y* x1 G分辨率为1280×720p/60Hz,行频为45kHz
8 ?% S1 i# @1 @/ W _ a0 F$ E
9 [* o$ ?7 [, i- {/ A' z* x' F2. 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)这些特征,用于图像处理。
$ |9 C; _4 Q7 i/ @. }, @% K2.2 camera特征
! u; b8 Q& X! L# y+ oMT6577内部集成的ISP,包含了一个功能强大的图像信号处理器,用于连接各种各样的图像传感器模组,这个处理器由时序产生单元(timing generated unit: TG)、镜头/传感器补偿(lens/sensor compensation)单元和图像处理单元。
" C ]% i/ W6 K6 u. V" w4 F支持的特征如下: (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)。 * \/ C0 H5 |/ V; [: _
(6) 3A统计和校正(statistics and correction) (7) 闪烁检测(flicker detection)。 + C4 n, Q4 D# g3 g0 N2 n0 {
2.3 camera框图
+ c j j3 c7 \图2 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)单元。 . K* L9 W2 r* o' X, [1 R# B! m5 j
在Bayer原始数据输入模式,镜头/传感器补偿(lens/sensor compensation)单元产生补偿的原始数据给色彩处理单元(color process unit);在YUV422/RGB565 输入模式,这步被忽略。
& v3 ^# k9 _. u+ V* D( U色彩处理单元接受来之镜头/传感器补偿(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 c1 J( O, u* q下面给出一些性能参数:
2 i4 l2 d3 Q9 w& K图3 ( F2 c# B/ E# U9 i+ ]
3. 原理图设计
7 f, Q1 ?2 M0 I4 WMT6577支持两路camera接口,一路是MIPI接口,一路是并行接口,这里我们采用的是并行接口,下面给出MT6577 CAM并行接口定义:
2 v* q6 @6 S5 S. U. K* R图4 Camera sensor连接座如下:
: q2 }! u5 |! O
图5 ! v9 {$ @8 {6 a% s
(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位。如下图:
* l5 R& p/ e- n% G
图6
/ _5 |: J6 L' @( N/ ]7 A; t* B7 |! I& x3 a4 A9 H
(2) OV5640IIC地址
0 J& l# C& {; P1 [# K# F( IIIC 8bit写地址为0x78,读地址为0x79,查询Sensor规格书可以看到:
% ?, [' o3 y% \4 N; w3 \图7 IIC 8bit地址最后一位为0时是写地址,为1时是读地址。这属于IIC通讯规则 8 ]. q8 Y, W z, M% t3 Q) S
# G4 ?3 n+ v2 v* p2 g" n1 F5 ^/ ?6 Z3 _* D
4. 驱动实现 : T2 q0 Y: W. m( u
; U+ `4 I3 R/ q9 W* n6 N& M" V4.1 相关代码 (1) CameraSensor驱动相关文件 \mediatek\custom\common\kernel\imgsensor\ov5642_yuv
( s4 O# H6 z+ D$ X* C+ {9 {2 j(2) SensorID和一些枚举类型的定义 \mediatek\custom\common\kernel\imgsensor\inc kd_imgsensor.h---------SensorID kd_imgsensor_define.h--------------一些枚举类型的定义 5 a- L; c$ |/ z% M/ h
(3) Sensor供电 \mediatek\custom\common\kernel\camera\camera kd_camera_hw.c和kd_camera_hw.h
; j3 V P- J: ]9 f, E1 f; [9 ?8 O3 u(4) KernelSpace的SensorList,imgsensor模块注册 \mediatek\custom\common\kernel\imgsensor\src kd_sensorlist.c和kd_sensorlist.h-----------camera模块加载 ' e2 _8 l% M- N Z5 ]
(5) UserSpace的SensorList,向用户空间提供支持的SensorList \mediatek\custom\common\hal\imgsensor\src\sensorlist.cpp 提供给用户空间的SensorList , O1 F. O2 M: R/ b6 i. z* E0 a
! c8 y2 w+ N' |, u) y! x( p* p(6) Sensor效果调整的接口 \mediatek\custom\common\hal\imgsensor\ov5642_yuv / Z0 x/ S% L9 i) q: V7 \; I( z
% v6 f! [1 _1 A. D0 \( C3 { g
4.2 针对OV5640的修改
8 [& M% B. p* X$ X9 y4.2.1 mediatek\config\hsimobile77_ics2\ProjectConfig.mk 0 a; W0 Q1 T# n8 d8 J2 x# o; Z" m
CUSTOM_KERNEL_IMGSENSOR=mt9p017_rawgc0329_yuv mt9p017_raw表示后置摄像头(也就是主摄像头),mt9p017是摄像头sensor驱动IC,raw是sensor一种输出的数据格式,是CCD或CMOS在将光信号转换为电信号时的电平高低的原始记录,单纯地没有将没有进行任何处理的图像数据,即摄像元件直接得到的电信号进行数字化处理而得到的。 $ O3 q9 o: x% Y: o& @6 m0 z
gc0329_yuv是前置摄像头,yuvsensor一种输出的数据格式,支持YUV/RGB格式的模组,一般会带有ISP(image single processor),经过A/D转换过的原始数据经过ISP处理生成YUV标准格式传到BB。
! x4 J5 I6 C# i( n) x我们采用的OV5640就带有ISP,输出YUV格式 2 b' a4 m4 ?2 l+ f' P
(1) 把mt9p017_raw 改为ov5640_yuv,去掉gc0329_yuv因为我们的产品没有后置摄像头 (2) 去掉类似CUSTOM_KERNEL_LENS后面的dummy_lens因为没有后置摄像头
. N+ q8 R8 q! ~1 H9 @9 O( |5 D修改之后的HAL层的配置: 4 q ^- n2 I# z. v
- CUSTOM_HAL_IMGSENSOR=ov5640_yuv
- CUSTOM_HAL_LENS=fm50afdummy_lens
- CUSTOM_HAL_MAIN_BACKUP_IMGSENSOR=
- CUSTOM_HAL_MAIN_BACKUP_LENS=
- CUSTOM_HAL_MAIN_IMGSENSOR=ov5640_yuv
- CUSTOM_HAL_MAIN_LENS=fm50af
- CUSTOM_HAL_MATV=
- CUSTOM_HAL_MSENSORLIB=mmc328xakm8975 ami304 yamaha530 mag3110 akmd8963
- CUSTOM_HAL_SENSORS=sensor
- CUSTOM_HAL_SUB_BACKUP_IMGSENSOR=
- CUSTOM_HAL_SUB_BACKUP_LENS=
- CUSTOM_HAL_SUB_IMGSENSOR=
- CUSTOM_HAL_SUB_LENS=dummy_lens
7 e) p9 p* \4 o- X) L. B' m 4 l! z# ]5 S: w( k+ z
]& H5 P) | g! T4 u
% _2 W/ h2 R8 i( o修改之后的kernel层的配置: 4 j9 \+ _" d7 Y! A# V
- CUSTOM_KERNEL_IMGSENSOR=ov5640_yuv
- CUSTOM_KERNEL_JOGBALL=
- CUSTOM_KERNEL_KPD=kpd
- CUSTOM_KERNEL_LCM=ili9806e
- CUSTOM_KERNEL_LEDS=mt65xx
- CUSTOM_KERNEL_LENS=fm50afdummy_lens
- CUSTOM_KERNEL_MAGNETOMETER=akm8975
- CUSTOM_KERNEL_MAIN_BACKUP_IMGSENSOR=
- CUSTOM_KERNEL_MAIN_BACKUP_LENS=
- CUSTOM_KERNEL_MAIN_IMGSENSOR=ov5640_yuv
- CUSTOM_KERNEL_MAIN_LENS=fm50af
- CUSTOM_KERNEL_MATV=
- CUSTOM_KERNEL_OFN=
- CUSTOM_KERNEL_RTC=rtc
- CUSTOM_KERNEL_SOUND=amp_6329pmic_2in1_spk
- CUSTOM_KERNEL_SUB_BACKUP_IMGSENSOR=
- CUSTOM_KERNEL_SUB_BACKUP_LENS=
- CUSTOM_KERNEL_SUB_IMGSENSOR=
- CUSTOM_KERNEL_SUB_LENS=dummy_lens 5 X; v; [2 \9 n3 C
; B$ R0 a4 B! {" B
7 A- C4 N7 Q: S. _4 A/ k
: L9 ~: c0 k( G: H5 H- s; w, G/ f0 f0 S5 H9 h' v) E
虽然我们没有后置摄像头,但不能去掉dummy_lens,我尝试过去掉之后用./mk r dr编译会提示下面的错误:
4 g) b J) j* \( O% f! J0 Y# a; h- P; Z O2 F* O
- 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'
- make[3]: ***[out/target/product/hsimobile77_ics2/obj/SHARED_LIBRARIES/libcameracustom_intermediates/LINKED/libcameracustom.so]Error 1 # G* A4 p1 I) e3 J: B1 r! H
7 Z& o5 {/ M } `& R$ ?* r- T* k
" l! b2 E/ y* C# n7 \, _9 k
1 N2 i2 x7 a% [3 g3 I n$ I
" W6 n: A, b9 X% Q, e
4.2.2 mediatek\custom\common\kernel\imgsensor----------kernel层 % v( j, a) [6 N3 K3 Q+ C7 y+ G
(1) 创建ov5640_yuv并建立需要的文件 # @) C* _0 }$ _
创建文件夹ov5640_yuv,把sensor IC厂家提供的ov5640yuv_Sensor.c放到此目录下。另外拷贝ov5642yuv_Sensor.h、ov5642yuv_Camera_Sensor_para.h、ov5642yuv_CameraCustomized.h拷贝过来改为ov5640yuv_Sensor.h等。 6 S: m; x' H2 R( P
编译发现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是没有这几个宏定义,我暂时定义如下:
& q6 D) {4 K9 A
: B1 ~5 S4 ?! ?- F# P- //kandi add startat 2014.11.29
- #defineOV5640_FULL_PERIOD_PIXEL_NUMS_HTS OV5640_FULL_PERIOD_PIXEL_NUMS
- #define OV5640_FULL_PERIOD_LINE_NUMS_VTS OV5640_FULL_PERIOD_LINE_NUMS
-
- #defineOV5640_PV_PERIOD_PIXEL_NUMS_HTS OV5640_PV_PERIOD_PIXEL_NUMS
- #define OV5640_PV_PERIOD_LINE_NUMS_VTS OV5640_PV_PERIOD_LINE_NUMS
/ S1 V+ `# F9 O2 A3 R 0 t3 y; m- g$ U/ O/ z
- p6 D2 q2 w, p
8 K+ u- L* ]7 F5 n/ @. u6 r7 o这是参考ov5642的相关定义来定义的。 4 O- J: J0 }- w
(2) 在支持的sensor列表中增加目标sensor
- `4 o+ Z2 O% p! u) s! Zmediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.h 在数组增加OV5640的内容,如下:
: H: t2 E8 e5 A# J# i$ L% Z* v% Q5 ~; W( P# {0 y
- ACDK_KD_SENSOR_INIT_FUNCTION_STRUCTkdSensorList[MAX_NUM_OF_SUPPORT_SENSOR+1] =
- {
- ………….
- #if defined(OV5640_YUV)
- {OV5640_SENSOR_ID,SENSOR_DRVNAME_OV5640_YUV, OV5640_YUV_SensorInit},
- #endif
- …………….
- } - ~4 j2 j9 \0 ?
7 ^& T( h' n$ \! {: O) @" \) W " W9 `/ b/ V# M+ q7 e( W2 o
Q& p K' ~5 g: k: @% U2 a K, x. j( V. p
也增加UINT32 OV5640_YUV_SensorInit(PSENSOR_FUNCTION_STRUCT*pfFunc); mediatek\custom\common\kernel\imgsensor\inc\kd_imgsensor.h (3) 增加sensor ID和字符串的定义
3 @& W7 |( ?7 B1 F% r/ y6 w
0 m) S' C' Z9 R' `$ L' P1 R3 |+ o- #defineOV5640_SENSOR_ID 0x5640
- #defineSENSOR_DRVNAME_OV5640_YUV "ov5640yuv" 3 A1 m. D9 H5 q, l
, v3 k @# K1 w! L& i
( b0 `4 `( j+ p9 c
: R% k N) [8 J4.2.3 mediatek\custom\common\hal\imgsensor---------------HAL层
' S+ Q+ v& M7 a(1) 创建ov5640_yuv文件夹 但这些文件夹下该有哪些文件,有需要哪些内容了,首先我对比了 ov3640_yuv和ov5642_yuv文件夹,只有cfg_ftbl_ov5642_yuv.h有差别:
图8
. e. o/ H+ A% I" ~这里主要是不同驱动IC支持的分辨率不同,以及设置默认的分辨率。
图9 7 N Y' `; i0 }1 L0 a
此文件下有两个这样的地方不同,这里是指自动对焦模式。
* L, y- w5 e( u( x' n( r因为我们的OV5640和OV5642非常接近,所以就直接把OV5642的目录复制过来修改为OV5640即可。
: `" h( [6 p* \8 y# i7 r+ v所以把mediatek\custom\common\kernel\imgsensor\ov5642_yuv拷贝到imgsensor目录下,改为ov5640_yuv
?) t5 o* Z4 {' i7 d+ J$ r! r(2) 在支持的sensor列表中增加目标sensor
( B e! y/ e2 N. p\src\ sensorlist.cpp
. h& D4 B6 O! h" y' A8 y% G' C' [5 z! y& x, B
- MSDK_SENSOR_INIT_FUNCTION_STRUCTSensorList[] =
- {
- ………..
- #ifdefined(OV5640_YUV)
- YUV_INFO(OV5640_SENSOR_ID,SENSOR_DRVNAME_OV5640_YUV, NULL),
- #endif
- …………
- }
7 Y: M. \' s% |0 f+ e) U 4 m0 @( n7 ]& i) ^: }' b" q
+ r* k, \: x4 F+ H) \9 Z! l) h
+ }8 N8 }% A5 k% M- S" y5 ?
注意:在 kd_SensorList.h 和 SensorList.cpp 里面添加驱动的时候要注意,Sensor 添加的位置要一样。否则驱动会跑乱,轻则 ISP 参数不对,重则 Sensor 无法启动。
. `6 D5 P$ }* U6 o- @' k z& f
E2 s; H0 b( u. a# Y* _ j9 o4.3 拍照图片尺寸设置 . _9 s& n% M' o: P# o
mediatek\custom\common\hal\imgsensor\ov5640_yuv\cfg_ftbl_ov5640_yuv.h : m9 O ^/ j* z% M q& F
1 Y0 e: ]7 J9 o& A% D% |
% d2 ^6 }1 r+ y6 Q
- // Capture Size
- CONFIG_FEATURE_SI(FID_CAP_SIZE,
- BY_DEFAULT(CAPTURE_SIZE_2560_1920),
- CAPTURE_SIZE_1280_960, CAPTURE_SIZE_1600_1200,
- CAPTURE_SIZE_2048_1536,CAPTURE_SIZE_2560_1920
- )
) v8 Q# ]5 K; L
/ f- T& f0 q' R3 q1 |# J
5 h! p9 D* @6 s% i# `5 u1 w. Y- F, M
4.4 Camera物理角度旋转 Cfg_setting_imgsensor.h 7 K8 u# C9 d' w* d' I
E: W* S6 J0 l- /*******************************************************************************
- * Image SensorOrientation
- *******************************************************************************/
- SensorOrientation_Tconst&
- getSensorOrientation()
- {
- static SensorOrientation_T const inst = {
- u4Degree_0 : 0,//270,//180,//90, // main sensor in degree (0, 90, 180, 270),kandi change from 90 to 180
- u4Degree_1 : 0, // sub sensor in degree (0, 90, 180, 270)
- };
- return inst;
- } 1 X# n- G( y* ^, N6 T8 S5 Q
/ @5 I0 i0 u6 s! J% F# L0 B
0 {! `* E/ A* ]( o
) ^# z" @2 d* a7 L7 @9 O# |& }: M( c" r4 m5 P: w
这几种都试过了,但都不行,预览和实际的都是成某种镜像关系。这是平台是提供旋转的功能。这个配置好了之后,如果方向不正确,可以通过驱动中的方向调整函数进行调整,如下: static void XXXXXSetMirror(kal_uint16ImageMirror) 参考:http://blog.csdn.net/loongembedded/article/details/41679977 " N5 Y5 }' N V" P- z
" Z( ~* b0 p/ U. R& R
2 j' N6 ^, O+ a& ?$ j4 ` 看了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)却问题依旧,很奇怪。 ! W; [9 R! D6 [/ M p
mediatek\custom\common\hal\imgsensor\ov5640_yuv\cfg_ftbl_ov5640_yuv.h
2 d9 T' I, A4 R! w. |* B0 u. Z# M# d- /*
- // Capture Size
- CONFIG_FEATURE_SI(FID_CAP_SIZE,
- BY_DEFAULT(CAPTURE_SIZE_2560_1920),
- CAPTURE_SIZE_1280_960, CAPTURE_SIZE_1600_1200,
- CAPTURE_SIZE_2048_1536,CAPTURE_SIZE_2560_1920
- )
- */
- // Capture Size
- CONFIG_FEATURE_SI(FID_CAP_SIZE,
- BY_DEFAULT(CAPTURE_SIZE_1920_2560),
- CAPTURE_SIZE_960_1280, CAPTURE_SIZE_1200_1600,
- CAPTURE_SIZE_1536_2048,CAPTURE_SIZE_1920_2560
- )
# j8 g, b L+ A U& r- y5 p$ K ' z$ S- T0 D4 U" {$ W" Y
9 E" s3 V- v8 N5 `' ]7 l我试过做上面的修改,但打开摄像头的时候,提示”Unfortunately, Camera has stopped” 本文作者:LoongEmbedded
3 N5 H2 v l m* `7 @9 N; p1 W) x) O( A' X5 | P& w* _
|