1、问题
见图:
和
2、解决方法
diff --git a/hardware/rk29/camera/CameraHal_Utils.cpp b/hardware/rk29/camera/CameraHal_Utils.cpp index 5b62f9d..a2423d7 100755 --- a/hardware/rk29/camera/CameraHal_Utils.cpp +++ b/hardware/rk29/camera/CameraHal_Utils.cpp @@ -193,7 +193,7 @@ extern "C" int rk_camera_zoom_ipp(int v4l2_fmt_src, int srcbuf, int src_w, int s ipp_req.flag = IPP_ROT_0; ipp_req.store_clip_mode =1; ipp_req.src0.w = cropW/scale_w_times; - ipp_req.src0.h = cropH/scale_h_times; + ipp_req.src0.h = cropH/scale_h_times - 8; ipp_req.src_vir_w = src_w; ipp_req.src0.fmt = IPP_Y_CBCR_H2V2; ipp_req.dst0.w = src_w/scale_w_times; diff --git a/hardware/rk29/camera/MessageQueue.cpp b/hardware/rk29/camera/MessageQueue.cpp index 61ee1f6..545f1d8 100755 --- a/hardware/rk29/camera/MessageQueue.cpp +++ b/hardware/rk29/camera/MessageQueue.cpp @@ -276,4 +276,3 @@ int MessageQueue::dump() return 0; }
同时参考如下文档:
在现在312x芯片代码中,少采几行几列:
1):
在rk_camera_setup_format()中:
else{ /* this is one frame mode*/
//rect->width -= 50;
//rect->height -= 8;
cif_crop = (rect->left + (rect->top <<16));
cif_fs = ((rect->width) + ((rect->height) <<16));
}
write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003);
改成:cif_fs = ((rect->width-8) + ((rect->height-8) <<16));
而不能直接在前面:
rect->width -= 8;
rect->height -= 8;
这里rect->width值后面还写了虚宽寄存器,这个值决定每行采集的宽度,如果CIF_CIF_SET_SIZE设置的采集宽小于这个虚空,那么每一行后面补0;即看到的是绿色;
(rect->height-8),表示每帧少采8行,也是补0;这里其实(rect->width-8),不是必须,每行不必少采集;
但这里这样修改后,会影响前置, 所以oneframe中不修改,还是在后置SP2518.c文件中修改:
static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)
{
SENSOR_TR("--hkw--mf->widthH(%dx%d)-----\n",mf->width,mf->height);
mf->height -= 8; //add
return 0;
}
,
另外在rk_camera_cifirq()函数中对if(reg_lastline != pcdev->host_height)有校验,所以去掉这边的判断:
pcdev->irqinfo.cifirq_idx++;
- if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
- pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
- RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
- reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
+ if (0) {//((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
+ //pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
+ // RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
+ // reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
2):
这样改不管是预览还是拍照尺寸都少采了8行;预览(8行不明显)和拍出来的照片底部均可能有绿条;
预览很可能看不到绿条,是因为预览图片是4:3(800x600)而lcd屏幕不是4:3,这样拿去显示合成时,有做裁剪缩放;
而拍出来的照片一定能看到绿条(1600x1200),
解决办法:
在拍照函数captureEncProcessPicture()中,强制进行RGA缩放,但输入给RGA的源高为实际值:frame->frame_height-16(实际是减8,但RGA需要16对齐);
git diff
diff --git a/CameraHal/AppMsgNotifier.cpp b/CameraHal/AppMsgNotifier.cpp
index eb96fff..686d95f 100755
--- a/CameraHal/AppMsgNotifier.cpp
+++ b/CameraHal/AppMsgNotifier.cpp
@@ -1035,15 +1035,16 @@ int AppMsgNotifier::captureEncProcessPicture(FramInfo_s* frame){
/*[email protected]: v0.4.7*/
// bool rotat_180 = false; //used by ipp
//frame->phy_addr = -1 ,just for isp soc camera used iommu,so ugly...
- if((frame->frame_fmt == V4L2_PIX_FMT_NV12) && ((frame->frame_width != mPictureInfo.w) || (frame->frame_height != mPictureInfo.h) || (frame->zoom_value != 100) || frame->phy
- output_phy_addr = rawbuf_phy;
+ //if((frame->frame_fmt == V4L2_PIX_FMT_NV12) && ((frame->frame_width != mPictureInfo.w) || (frame->frame_height != mPictureInfo.h) || (frame->zoom_value != 100) || frame->p
+ if(1){
+ output_phy_addr = rawbuf_phy;
output_vir_addr = rawbuf_vir;
#if 0
arm_camera_yuv420_scale_arm(V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV12, (char*)(frame->vir_addr),
(char*)rawbuf_vir,frame->frame_width, frame->frame_height,
jpeg_w, jpeg_h,false,frame->zoom_value);
#else
- rga_nv12_scale_crop(frame->frame_width, frame->frame_height,
+ rga_nv12_scale_crop_cap(frame->frame_width, frame->frame_height-16,
(char*)(frame->vir_addr), (short int *)rawbuf_vir,
jpeg_w,jpeg_w,jpeg_h,frame->zoom_value,false,!mIs_Verifier,false);
#endif
3):
这样出现拍照的结果:绿条在图片的上方;增加下面的修改,rga的源虚高要以实际的,比如(1600x1200)图片,实际是1200-8,这里Rga_Request.src.vir_h还是1200;
:
cropW = src_width;
cropH = src_height; //src_height即frame->frame_height-16;
Rga_Request.src.act_w = cropW;
Rga_Request.src.act_h = cropH;
这样RGA所做的,即从源1600x(1200-8)到1600x1200的裁剪缩放过程;
diff --git a/CameraHal/CameraHalUtil.cpp b/CameraHal/CameraHalUtil.cpp
index f73c7e8..a174156 100755
--- a/CameraHal/CameraHalUtil.cpp
+++ b/CameraHal/CameraHalUtil.cpp
@@ -450,7 +450,7 @@ extern "C" int rga_nv12_scale_crop(int src_width, int src_height, char *src, sho
Rga_Request.src.uv_addr = (int)psY;
Rga_Request.src.v_addr = 0;
Rga_Request.src.vir_w = src_width;
- Rga_Request.src.vir_h = src_height;
+ Rga_Request.src.vir_h = src_height+16;
Rga_Request.src.format = RK_FORMAT_YCbCr_420_SP;
Rga_Request.src.act_w = cropW;
Rga_Request.src.act_h = cropH;
4)
但是这个rga_nv12_scale_crop()不仅在拍照时使用,zoom等其他场合可能都用了,所以这里单独增加一个给拍照时用的RGA函数:
2) 中:rga_nv12_scale_crop()
改成:
rga_nv12_scale_crop_cap()
3)中:
rga_nv12_scale_crop()改回去,增加rga_nv12_scale_crop_cap()函数;区别是:
- Rga_Request.src.vir_h = src_height;
+ Rga_Request.src.vir_h = src_height+16;
CameraHal.h中增加声明:
diff --git a/CameraHal/CameraHal.h b/CameraHal/CameraHal.h
index f1e8e8c..505f22e 100755
--- a/CameraHal/CameraHal.h
+++ b/CameraHal/CameraHal.h
@@ -118,6 +118,7 @@ extern "C" int cameraFormatConvert(int v4l2_fmt_src, int v4l2_fmt_dst, const cha
bool mirror);
extern "C" int rga_nv12_scale_crop(int src_width, int src_height, char *src, short int *dst, int dstbuf_width,int dst_width,int dst_height,int zoom_val,bool mirror,bool isNeedC
+extern "C" int rga_nv12_scale_crop_cap(int src_width, int src_height, char *src, short int *dst, int dstbuf_width,int dst_width,int dst_height,int zoom_val,bool mirror,bool isN
extern rk_cam_info_t gCamInfos[CAMERAS_SUPPORT_MAX];