高通5Mcamera在BMP10平台上总结.docx

上传人:b****6 文档编号:6630789 上传时间:2023-01-08 格式:DOCX 页数:20 大小:1.18MB
下载 相关 举报
高通5Mcamera在BMP10平台上总结.docx_第1页
第1页 / 共20页
高通5Mcamera在BMP10平台上总结.docx_第2页
第2页 / 共20页
高通5Mcamera在BMP10平台上总结.docx_第3页
第3页 / 共20页
高通5Mcamera在BMP10平台上总结.docx_第4页
第4页 / 共20页
高通5Mcamera在BMP10平台上总结.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

高通5Mcamera在BMP10平台上总结.docx

《高通5Mcamera在BMP10平台上总结.docx》由会员分享,可在线阅读,更多相关《高通5Mcamera在BMP10平台上总结.docx(20页珍藏版)》请在冰豆网上搜索。

高通5Mcamera在BMP10平台上总结.docx

高通5Mcamera在BMP10平台上总结

高通BMP1.0平台调试5MCMOScamera总结

摘要:

本文着重解决BMP1.0平台上的RAWdata输出数据的500万camerasensor的调试。

包括驱动层,应用层代码和camera镜头的色彩校准。

我们按照调试的先后顺序进行步骤说明:

我们先说OEM层。

OEM层继承了ICAMERA的所有功能,ICAMERA只是一个壳,实现会转到OEMCAMERA。

AEE层介于两者之间,公开的代码只是让我们参考,修改无效。

在我们需要使用camera时候,调用CreateCamera,在CreateInstance获得句柄后,我们得到一个应用的壳,然后得到具体的与camera应用相关的函数注册。

然后通过OEMCamera_SetParm开始启动ACM相关资源,ACM简单的理解,就是图片和相关分支调用函数。

详情看OEMCamera_ACMTransaction()相关函数,这里不是重点,因此点到即止。

因为高通在双camera的资源应用上还没有完善,日后和应用在ACM上可能遇上问题,因此才在这里顺带说一下。

各位有兴趣可以和应用的多交流。

现在,我们可以从OEMCamera_New()开始,对驱动设计工程师而言,可以理解为camera代码应用的开始。

OEMCamera_New()中,camera_get_sensors所用到的变量,在代码启动的时候已经赋值,因此,并不是为空,这点需要注意,另外,这里还没有开始分配camera提供显示的内存空间,主要是对camera硬件相关进行初始化(想深入了解,看graph_task中的camera_init,这是在service层注册过的函数,再往下说,我怕会开始跑火车,就在这里点到即止,很多东西我们可以从代码中看到更多。

我这里提点一下就好)

经常,我们需要trace看sensorInfo里面的信息。

我们最关心的是sensor_width和sensor_height,这个是从底层获取的camera输出图像的尺寸。

从代码的设计上看,AEECLSID_CAMERA1固定的表示主摄像头,AEECLSID_CAMERA2表示从摄像头(现在手机一般都是双camera,因此单camera的流程就不说了)

现在我们非常关心sevice层的camera应用,在这里涵盖了camera绝大多数的基础代码(指公共服务的接口,)这个文件里的函数,需要认真研究。

首先,我们研究preview的部分:

camera_malloc_preview_buffers(),可以看到camera_preview_buffers.buffers[current_buffer].buf_ptr表示preview的buffer的指针,共5块,前3块是给VFE用的,后2块是显示overlay用的。

VFE处理video数据流,图像效果处理,raw数据解析(包括rolloff,gamma,ASF,AWB相关),YCBCR格式拍照解析

显示overlay用途,包括录像buffer的缓冲,屏幕显示的重载。

在rawdatabuffer中,会带上buffer头标志"QCAMRAW",只有带这个标志的rawbuffer,才是合法的,可以参看qcamrawIsHeader()这个函数判断,具体头里面有多少内容,看qcamrawSetHeader()这个函数,很直观的就能解析,这里就不在赘述。

想看preview关于buffer的指针定义,有一个函数camera_set_preview_buffers()很方便,这里面还包括recoding部分的buffer指针定义。

这里提供一个函数camera_calculate_output1_framerate(),可以看到如何用软件的方式看camerapreview的帧率,我用过,和实际用示波器查看的结果非常接近,考虑帧率的动态变化,实际用软件的方式比示波器更好。

如果我们想对camera的数据进行一些深入的修改,建议从两个函数入手去追溯:

camera_process_qdsp_output1_msg和camera_process_qdsp_output2_msg,这里面有很多图像处理。

Output1进行preview;output2进行snapshot。

Snapshot的thumbnail放在output1处理。

图像的旋转,camera_svcs_blt_ex(0这个函数是需要的,注意Y和CbCr是分开存放的。

若是还想向上追溯,可以参看camera_svcs_process_func(),这里是camera一些主要公共功能的消息派发点。

具体看函数内部就明白,我就不多说了。

constcamera_bestshot_config_typecamera_bestshot_table[]={#include"camera_bestshot_config.h"};这个是场景模式的入口,从camera_svcs_bestshot_get_config这里开始,将场景的索引赋值给cam3a_awb_state.bestshot_config,从这个关键词,我们能搜索到后面所有的功能。

关于ZOOM的相关流程,这里说明一下:

camera_svcs_set_dimensions()可以看到zoom的放大倍率的计算。

ui_picture_width=FLOOR16(camsensor_static_params[camera_asi].full_size_width-pad_pixels);

ui_picture_height=FLOOR16(camsensor_static_params[camera_asi].full_size_height-pad_lines);

如果是rawdata格式的数据:

pad_pixels=12;

pad_lines=8;

这是预留的边框,防止后面计算出错,然后我们看到处理了ui_picture_width和ui_picture_height后,其值一定是偶数。

resize_factor=(camsensor_static_params[camera_asi].full_size_height*Q12/max_crop_height(或者max_crop_width,哪个数小取哪个,这样保证放大能填充整个屏幕));这里计算能够放大的倍率因子

if(camera_min_decimation

found_min)

{

camera_parm_zoom_table.minimum_value=(int32)i;

found_min=TRUE;

}

if(resize_factor

{

camera_parm_zoom_table.maximum_value=(int32)i;

break;

}

通过camera_min_decimation和camera_zoom_table[]的比较,确定最小的ZOOM起始位置,这个位置其实是zoom的最大值,一般我们得到的是0值,告诉VFE按照camera的原始尺寸处理图像。

而camera_parm_zoom_table.maximum_value所表示的是zoom缩小的最大比例。

从上边的解释,我们看到,ZOOM所能放大,缩小的比率,和我们camerasensor能输出的最大尺寸,UI能设定的最大尺寸,还有屏幕能表现的尺寸有关系,通过改变这些值,我们能够按照需要放大,缩小图像。

通过上面的计算,我们得到camera_parm_zoom.minimum_value和camera_parm_zoom.maximum_value和camera_parm_zoom.step_value,这是我们最后能利用的zoom范围和每一步zoom的步长。

接下来如何zoom,就不多说了,因为出错的可能性很小。

以上属于部分camera的应用,后面在色彩校准部分还会介绍3a方面的应用。

下面我们来讨论一下camerasensor驱动代码

我们按照函数调用顺序进行说明:

1.camsensor_xxx_init():

顾名思义,其代表的功能定义就不用再说了,这里只需要解释一下里面的一个变量camsensor_preview_resolution,它可以赋值CAMSENSOR_QTR_SIZE和CAMSENSOR_FULL_SIZE,QTR是预览尺寸,FULL是拍照尺寸。

我们在调试的时候,要是怀疑拍照相关参数问题,可以在预览流程中看拍照的图片进行debug。

发布出来给客户的,就只需要QTR的设置。

2.camsensor_xxx_start():

这个函数太太太太太太重要了(我有点蛋疼了),这个函数是驱动的灵魂,因为可以说的问题太多,一时之间都不知道怎么说(这话说的有点招臭鸡蛋)。

这样,望文生义的地方我就不说了,讲讲容易犯错的地方。

camif_config相关配置,其实已经没有用了,但是我们还是保留其设置(谁知道以后会不会又需要用上)。

camsensor_params->chromatix_parms=&camsensor_chromatix_xxx_struct;这是tuning图像的所有参数的集合文件头。

Tuning后面我们会说.

camsensor_params->raw_output_option=CAMSENSOR_8_BIT_DIRECT;虽然还有CAMSENSOR_10_BIT_DIRECT这个参数可以选择,但由于后端数据的存储都是按照8Bit来处理,因此这个参数没有什么太大的意义(这个最终解释权在我这里,以后高通会不会将其区别开来,这要用发展的眼光来看).

在这个函数里,有判断camsensor_preview_resolution变量,这是为了调试全尺寸的需要而设置的,在正常流程中使用,我们只需要CAMSENSOR_QTR_SIZE这个分支,在实际的调试中,我发现,利用好CAMSENSOR_FULL_SIZE这个参数能方便解决拍照相关的很多问题。

至于怎么利用,说起来头疼,简单的说,在第一点使用camsensor_preview_resolution=CAMSENSOR_FULL_SIZE即可,至于这样做会有什么问题,就要看驱动代码的健壮否了。

这里无法做太多预测。

preview_dx_decimation:

这个是VFE处理bayer格式数据给显示屏用的,这个是太太太重要了(我真无聊)。

有一个边界计算的问题(边界的意思,就是在数学计算的时候,我们要保证图像处理时候,作为分母的数据不能取为0,否则有严重的后果,嘿嘿,为什么会取为0呢?

因为图片边界外面就是0了),其要求在尺寸上,宽度预留12pixel,高度预留8pixel(VFE实际只需要高度裁边6pixel,但是为了整齐,我们裁剪了5+3=8pixel),然后剩下的宽和高的尺寸各自还要能被4整除。

有人说不这样做行吗?

太麻烦啦,我说可以,但是准备后面的色彩调整时候,屏幕显示总偏色的代价。

在6平台上特别是偏绿。

接下来是AF参数设置,这个放到AF中再说。

AF对焦,只取屏幕的1/4尺寸给VFE计算,可以减少计算量,提高对焦速度。

camsensor_params->pixel_clock和pixel_clock_per_line这个参数是如此的重要,怎么说都是重点,这个重点中的重点,我只能用这种方式表达我对这个参数的尊重之情。

它是用来计算flicker,也可以叫banding,一个意思。

这参数属于tuning范畴,因此如何确定这些参数,归在后面tuning进行解释,这里先提点一下。

pclk_invert:

不同的厂家,pclk有效的极性可能不一样,因此我们需要判断,设TRUE表示上升沿有效,FALSE表示下降沿有效,如何判断呢?

规格书中看看一目了然,下面这张就是上升沿有效的示意图

camif_config.HsyncEdge和camif_config.VsyncEdge:

有CAMIF_High和CAMIF_Low两种选择,表示行场同步信号的有效电平,高或低有效,只要用示波器看看camera的数据线输出是在行场低还是在高的时候有,就能直观的判断。

当然,规格书中也会提及,下面这张就是行场高有效的典型示意图。

3.camsensor_xxx_snapshot_config():

这个是拍照时候调用的设置函数。

简单说一下里面的一些参数好了:

discardFirstFrame=TRUE,表示在将来需要切换到预览模式时,会将预览的第一帧数据抛弃,这么做是为了防止第一帧数据残缺造成切换时候显示错乱的现象。

但是仅仅这么做还不够(从中可以看到,高通虽然想到这个问题,但是其仅仅停留在实验室阶段),这样做,仅仅将数据传输的错误解决,但是分配显示buffer时候的随机数(malloc并不清空Buffer内容)没有处理,这样将会在切换到预览模式的时候显示花屏。

我们在service层,找到camera_malloc_preview_buffers(),需要在其中添加如下代码:

if(camera_preview_buffers.buffers[current_buffer].buf_ptr)

{

memset(camera_preview_buffers.buffers[current_buffer].buf_ptr,

0x7f,

camera_preview_buffer_size);

camera_set_preview_headers();

}

camif_window_width_config.firstPixel,camif_window_height_config.firstLine这是用来调整显示像素顺序不对,而bayer的format无法调整的时候,这里提供一个变相的调整format的机会,让显示的色彩正确,至于是减多少,需要实际调试判断,原理就不说了,找资料看去。

epoch_line,这是纠错处理,当一帧数据的行超出这个设定的最大行时候,会有出错中断,提示帧错误。

将这个值设置的很大,将永远不会发生这个事件,相当于disable。

我建议最好disable,因为有一些变态的sensor,会输出很大的dummyline,看起来很变态,但是必须。

4.camsensor_xxx_raw_snapshot_config();这个函数是在后续tuning的时候,拍rawdata照片的时候需要,设置同上。

5.camsensor_xxx_video_config():

预览配置函数。

其实没什么好说的,要说的前面都说了,要是这里还有什么不明白的,可以打114问。

我就不在这里骗稿费了。

6.camsensor_xxx_power_up();其实我不想说,这个函数真的很雷人,要是你相信在这里进行powerup的话,我相信你的camera永远都别正常工作。

7.camsensor_xxx_power_down():

这个函数还算正常一些,但是不需要在这里closemclk的操作。

在退出camera模块的时候,系统会有流程关闭工作时钟。

8.camsensor_xxx_register():

这个函数写这里,但是我不想说了(我看起来很欠揍)。

9.camsensor_xxx_real_to_register_gain()和camsensor_xxx_register_to_real_gain():

这两个函数才是重点。

说起来有点意思:

这两函数,是浮点数和寄存器表示的整数之间的转化关系。

举个具体的例子比较容易说明。

OV5647:

gain寄存器最大0x3FF,小数占用4bit,因此形象的表示浮点数为3F.F,整数0x3F,小数一个F。

从曝光表中抽取一个数值{912,600},/*Gain=3.563ExposureIndex=259*/下面的计算是real_to_register:

reg_gain=(uint16)real_gain;//real_gain=3.563reg_temp=reg_gain<<4;//只取整数部分gain=reg_temp|(((uint16)((real_gain-(float)reg_gain)*16.0))&0x0f);//整数和小数部分合并下面是register_to_real的计算部分:

real_gain=(float)((float)(reg_gain>>4)+(((float)(reg_gain&0x0f))/16.0));//reg_gain是寄存器整数表示的3.563.

10.camsensor_ov5647_truly_sensor_setting():

这个是sensor的参数集合的函数,用来对sensor初始化,预览和拍照参数的设定。

具体的意义这里就不详细解说,一般由sensor厂家完成。

11.camsensor_xxx_get_snapshot_fps():

将预览/拍照的图片尺寸比较,默认预览30fps,得到拍照的速率,这个,用在ISO,计算曝光行,去除拍照的第一帧数据,防抖动处理。

12.camsensor_xxx_get_preview_lines_per_frame():

计算ISO曝光时间用的,公式如下:

preview_exposuretime=(forced_input.forced_line_count)/(preview_exposuretime*preview_linesPerFrame);

13.camsensor_xxx_get_preview_pixels_per_line():

用来计算flicker,公式计算如下:

if(camctrl_tbl.get_preview_pixels_per_line){cam3a_aec_state.band_60hz_gap=(float)(((float)1/120)*(((float)(camsensorParamsPtr->pixel_clock))/((float)(camctrl_tbl.get_preview_pixels_per_line()))));}else{cam3a_aec_state.band_60hz_gap=(float)(((float)1/120)*(((float)(camsensorParamsPtr->pixel_clock))/((float)(camsensorParamsPtr->pixel_clock_per_line))));}

14.camsensor_xxx_get_snapshot_lines_per_frame():

:

用来计算拍照的曝光行:

output.snapshot_linecount=(uint32)(((snapshot_exposuretime*snapshot_linesPerFrame*snapshot_fps)/Q8)+0.5);

15.camsensor_xxx_get_snapshot_pixels_per_line():

目前没有用处。

16.camsensor_xxx_get_snapshot_max_exposure_line_count():

设定拍照的最大曝光行,可以用来限制允许拍照的曝光行边界,这个边界是可以动态变化的,这样拍照的曝光时间就可以控制:

限定代码如下:

output.snapshot_linecount=(uint32)(((snapshot_exposuretime*snapshot_linesPerFrame*snapshot_fps)/(Q8*snapshot_fps_divider))+0.5);

17.camsensor_xxx_set_snapshot_frame_rate():

没啥用,返回设为TRUE即可。

18.camsensor_xxx_set_snapshot_exposure_gain():

这个函数是用来对拍照的gain和line进行写入sensor操作,我们为了防止拍照的时候噪声,一般会将gain/2,而line*2.

19.camsensor_xxx_setup_camctrl_tbl():

几个标志要说明一下:

awb_low_light_CC_is_supported=TRUE;CC是colorcorrection的缩写,为色彩校正的意思,对bayer格式的数据而言,那是一定要设置的。

fast_convergence_is_supported:

是对AEC进行是否快速计算的意思,如果luma计算的进度在实际测试中发现偏差过大(超过2个点,2个点是默认设置,我们可以更改,这在后面的tuning中说明),就需要禁止这个标记。

enable_sensor_rolloff_correction:

和set_lens_correction标记是一个意思,这个标记要小心设置,当确定不用VFE进行后端rolloff计算,才可以使能这个设置,否则一定要关闭,要不tuning的时候,色彩无法校准。

enable_rolloff_correction:

这个标记正好和上面的相反,需要VFE进行rolloff设置的时候,我们需要使能它。

至于rolloff是啥东西,后面tuning再解释。

af_is_supported,af_use_isp,cam3a_af_state.is_enabled,这三个标记,是用来激活Af功能的,要用isp的AF功能,上面三个标记都要设TRUE,要是用VCM通过i2c来激活af功能,af_use_isp设为FALSE,另外两设为TRUE.

20.aec_digital_gain_is_supported:

这是用在CC的校验中,可以在WB中增强RGB色彩矩阵的变化,另外在拍照ISO设置中,必须配合ISO使能iso_is_supported标志才能起作用,

好了,到此driver的说明告一段落。

下面我们来说AF的调试。

先说VCM的调试。

1.camsensor_xxx_set_default_focus:

我们一般将镜头设置在无穷远的位置。

这样启动camera的时候,看远处会比较清晰。

2.camsensor_xxx_move_focus:

参数step_direction代表的是每一步对焦的步长,理论上这个值越小,对焦越精确,当然,我们调试是不能完全按照理论来的。

一般我们会设置15~20。

AF对焦调整,有两种模式,下面介绍一下各个参数的意义

其一为通过VCM马达驱动

camsensor_params->

af_enable使能此功能

num_steps_near_to_far步长总数

num_steps_near_to_closest_infinity默认值

num_gross_steps_between_stat_points粗调步长

num_fine_st

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 工作计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1