955 lines
24 KiB
C
Executable File
955 lines
24 KiB
C
Executable File
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/types.h>
|
||
#include <sys/time.h>
|
||
#include <sys/mman.h>
|
||
#include <sys/ioctl.h>
|
||
#include <sys/select.h>
|
||
#include <asm/types.h>
|
||
#include <linux/videodev2.h>
|
||
#include <time.h>
|
||
#include <linux/fb.h>
|
||
#include <pthread.h>
|
||
#include <semaphore.h>
|
||
#include "csi.h"
|
||
#include "disp.h"
|
||
#if MODULE_CSI_COMPILE_CFG == 1
|
||
|
||
enum v4l2_resolution{
|
||
V4L2_RESOLUTION_UXGA =0,
|
||
V4L2_RESOLUTION_720P =1,
|
||
V4L2_RESOLUTION_XGA =2,
|
||
V4L2_RESOLUTION_SVGA =3,
|
||
V4L2_RESOLUTION_VGA =4,
|
||
V4L2_RESOLUTION_QVGA =4,
|
||
};
|
||
|
||
int VFLip=1, HFLip=3;
|
||
|
||
/*********************************************************************************************************
|
||
*
|
||
* Static Define
|
||
**********************************************************************************************************/
|
||
#define CSI_CLAR(x) memset(&(x), 0, sizeof(x))
|
||
|
||
/*********************************************************************************************************
|
||
*
|
||
* Static Variable
|
||
**********************************************************************************************************/
|
||
static INT8U CSI_LOG = 1;
|
||
#define CSI_DBG_LOG if(CSI_LOG) printf
|
||
|
||
INT8U *csi_last_down_smpl_buf = NULL;
|
||
INT8U *csi_cur_down_smpl_buf = NULL;
|
||
INT8U csi_smpl_buf_compare_flag = 0;
|
||
|
||
/*********************************************************************************************************
|
||
*
|
||
* Extern And Global Variable
|
||
**********************************************************************************************************/
|
||
INT32S csi_v4l2_fd;
|
||
CSI_BUF csi_buf;
|
||
pthread_mutex_t csi_lock;
|
||
INT32S csi_ctrl_set(INT32S fd,INT32U id,INT32S val)
|
||
{
|
||
struct v4l2_control control;
|
||
INT32S ret;
|
||
control.id = id;
|
||
control.value = val;
|
||
|
||
ret = ioctl(fd, VIDIOC_S_CTRL, &control);
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_get_fd()
|
||
{
|
||
return csi_v4l2_fd;
|
||
}
|
||
|
||
#if 0
|
||
/*********************************************************************************************************
|
||
*
|
||
* Function Define
|
||
**********************************************************************************************************/
|
||
INT32S csi_ctrl_set(INT32S fd, CSI_CTRL_ID ctrlId, INT32S ctrlVal)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_queryctrl queryctrl;
|
||
struct v4l2_control control;
|
||
#define V4L2_CID_RESOLUTION (V4L2_CID_BASE+19)
|
||
#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20)
|
||
#define V4L2_CID_FLIP (V4L2_CID_BASE+31)
|
||
#define SW_ROTATE 4
|
||
#define NO_ROTATE 5
|
||
#define V4L2_CID_LIGHT_FREQ (V4L2_CID_BASE+24)
|
||
|
||
if(ctrlId >= CSI_CTRL_ID_MAX){
|
||
CSI_DBG_LOG("%s:param error\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_CLAR(queryctrl);
|
||
CSI_CLAR(control);
|
||
|
||
if(ctrlId == CSI_CTRL_ID_SET_RESOLUTION){
|
||
|
||
queryctrl.id = V4L2_CID_RESOLUTION;
|
||
control.id = V4L2_CID_RESOLUTION;
|
||
switch(ctrlVal)
|
||
{
|
||
case SENSOR_RESOLUTION_1920X1080: control.value = V4l2_API_RESOLUTION_720P; break;
|
||
case SENSOR_RESOLUTION_1280X720: control.value = V4l2_API_RESOLUTION_720P; break;
|
||
case SENSOR_RESOLUTION_640X480: control.value = V4l2_API_RESOLUTION_VGA; break;
|
||
default: control.value = queryctrl.default_value;
|
||
}
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_HUE){
|
||
queryctrl.id = V4L2_CID_HUE;
|
||
control.id = V4L2_CID_HUE;
|
||
switch(ctrlVal)
|
||
{
|
||
case HUE_NONE: control.value = V4l2_API_COLORFX_NONE; break;
|
||
case HUE_MONO: control.value = V4l2_API_COLORFX_BW; break;
|
||
case HUE_NEGATIVE: control.value = V4l2_API_COLORFX_NEGATIVE; break;
|
||
case HUE_RETRO: control.value = V4l2_API_COLORFX_SEPIA; break;
|
||
case HUE_SKY_BLUE: control.value = V4l2_API_COLORFX_SKY_BLUE; break;
|
||
case HUE_GRASS_GREEN: control.value = V4l2_API_COLORFX_GRASS_GREEN; break;
|
||
default: control.value = queryctrl.default_value;
|
||
}
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_AUTO_AWB){
|
||
queryctrl.id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE;
|
||
control.id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE;
|
||
|
||
switch(ctrlVal)
|
||
{
|
||
case AWB_AUTO: control.value = V4l2_API_WHITE_BALANCE_AUTO; break;
|
||
case AWB_SUNNY: control.value = V4l2_API_WHITE_BALANCE_CLOUDY; break;
|
||
case AWB_OVERCAST: control.value = AWB_OVERCAST; break; // T.B.D
|
||
case AWB_DAYLIGHT: control.value = V4l2_API_WHITE_BALANCE_DAYLIGHT; break;
|
||
case AWB_MANUAL: control.value = V4l2_API_WHITE_BALANCE_MANUAL; break;
|
||
case AWB_INCANDESCENCE: control.value = V4l2_API_WHITE_BALANCE_INCANDESCENT; break; // <20><><EFBFBD><EFBFBD>ɫ
|
||
case AWB_FLUORESCENT: control.value = V4l2_API_WHITE_BALANCE_FLUORESCENT; break; // ӫ<><D3AB>ɫ
|
||
case AWB_TUNGSTEN: control.value = V4l2_API_WHITE_BALANCE_TUNGSTEN; break; // <20><>ɫ
|
||
case AWB_HORIZON: control.value = V4l2_API_WHITE_BALANCE_HORIZON; break; // T.B.D
|
||
case AWB_FLASH: control.value = V4l2_API_WHITE_BALANCE_FLASH; break; // T.B.D
|
||
case AWB_SHADE: control.value = V4l2_API_WHITE_BALANCE_SHADE; break; // T.B.D
|
||
default: control.value = queryctrl.default_value;
|
||
}
|
||
}
|
||
else if(ctrlId == CSI_CTRL_ID_SET_AE){
|
||
queryctrl.id = V4L2_CID_EXPOSURE;
|
||
control.id = V4L2_CID_EXPOSURE;
|
||
|
||
if(ctrlVal >= -4 && ctrlVal <= 4){
|
||
control.value = ctrlVal;
|
||
}else{
|
||
control.value = queryctrl.default_value;
|
||
}
|
||
}
|
||
else if(ctrlId == CSI_CTRL_ID_SET_LIGHT_FREQ){
|
||
queryctrl.id = V4L2_CID_LIGHT_FREQ;
|
||
control.id = V4L2_CID_LIGHT_FREQ;
|
||
switch(ctrlVal)
|
||
{
|
||
case LIGHT_FREQ_MODE_50_HZ: control.value = V4l2_API_LIGHT_FREQ_50Hz; break;
|
||
case LIGHT_FREQ_MODE_60_HZ: control.value = V4l2_API_LIGHT_FREQ_60Hz; break;
|
||
default: control.value = queryctrl.default_value;
|
||
}
|
||
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_FLIP){
|
||
queryctrl.id = V4L2_CID_FLIP;
|
||
control.id = V4L2_CID_FLIP;
|
||
switch(ctrlVal)
|
||
{
|
||
case VFLIP_SET_ZERO: control.value = SW_ROTATE; break;
|
||
case VFLIP_SET_POS1:
|
||
if(VFLip) VFLip = 0;
|
||
else VFLip = 1;
|
||
control.value = VFLip;
|
||
break;
|
||
case HFLIP_SET_ZERO: control.value = NO_ROTATE; break;
|
||
case HFLIP_SET_POS1:
|
||
if(HFLip == 2) HFLip = 3;
|
||
else HFLip = 2;
|
||
control.value = HFLip;
|
||
break;
|
||
default: control.value = queryctrl.default_value;
|
||
}
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_BRIGHTNESS){
|
||
queryctrl.id = V4L2_CID_BRIGHTNESS;
|
||
control.id = V4L2_CID_BRIGHTNESS;
|
||
|
||
if(ctrlVal >= -4 && ctrlVal <= 4){
|
||
control.value = ctrlVal;
|
||
}else{
|
||
control.value = queryctrl.default_value;
|
||
}
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_SATURATION){
|
||
queryctrl.id = V4L2_CID_SATURATION;
|
||
control.id = V4L2_CID_SATURATION;
|
||
|
||
if(ctrlVal >= -4 && ctrlVal <= 4){
|
||
control.value = ctrlVal;
|
||
}else{
|
||
control.value = queryctrl.default_value;
|
||
}
|
||
}else if(ctrlId == CSI_CTRL_ID_SET_AG){
|
||
queryctrl.id = V4L2_CID_AUTOGAIN;
|
||
control.id = V4L2_CID_AUTOGAIN;
|
||
|
||
if(ctrlVal >= -4 && ctrlVal <= 4){
|
||
control.value = ctrlVal;
|
||
}else{
|
||
control.value = queryctrl.default_value;
|
||
}
|
||
}
|
||
|
||
ret = ioctl(fd, VIDIOC_S_CTRL, &control);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:ioctl v4l2 set control.id = %d, control.value = %d error!!!\r\n", __func__, control.id, control.value);
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_DBG_LOG("%s:control.id = %d, control.value = %d\r\n", __func__, control.id, control.value);
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
INT32S csi_input_set(INT32S fd, INT32U idx)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_input input;
|
||
|
||
CSI_CLAR(input);
|
||
|
||
input.index = idx;
|
||
ret = ioctl(fd, VIDIOC_S_INPUT, (void *)&input);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 input set error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
INT32S csi_steam_param_set(INT32S fd, INT16U frmRate)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_streamparm streamparam;
|
||
|
||
CSI_CLAR(streamparam);
|
||
|
||
streamparam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
streamparam.parm.capture.timeperframe.numerator = 1;
|
||
streamparam.parm.capture.timeperframe.denominator = frmRate;
|
||
streamparam.parm.capture.capturemode = V4L2_MODE_VIDEO;
|
||
ret = ioctl(fd, VIDIOC_S_PARM, (void *)&streamparam);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 streamparam set error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_fmt_set(INT32S fd, INT16U width, INT16U height, INT32U fmt)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_format format;
|
||
INT16U sensorWidth = 0, sensorHeight = 0;
|
||
if((width == 1920) && (height == 1080)){
|
||
ret = csi_steam_param_set(csi_v4l2_fd, CSI_INPUT_1080P_FRM_RATE);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:set csi 1080P frame rate error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
}else{
|
||
ret = csi_steam_param_set(csi_v4l2_fd, CSI_INPUT_720P_FRM_RATE);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:set csi 720P frame rate error!\r\n", __func__);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
}
|
||
if((width == 1920) && (height == 1080)){
|
||
sensorWidth = 1920;
|
||
sensorHeight = 1080;
|
||
}else{
|
||
sensorWidth = width;
|
||
sensorHeight = height;
|
||
}
|
||
|
||
CSI_CLAR(format);
|
||
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
format.fmt.pix.width = sensorWidth;
|
||
format.fmt.pix.height = sensorHeight;
|
||
format.fmt.pix.pixelformat = fmt;
|
||
format.fmt.pix.field = V4L2_FIELD_NONE;// V4L2_FIELD_INTERLACED
|
||
ret = ioctl(fd, VIDIOC_S_FMT, (void *)&format);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 format set error!\r\n", __func__);
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
ret = ioctl(fd, VIDIOC_G_FMT, (void *)&format);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 format get error!\r\n", __func__);
|
||
ret = -4;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_DBG_LOG("Senor Resolution = %dX%d\n",format.fmt.pix.width,format.fmt.pix.height);
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_querycap_get(INT32S fd)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_capability cap;
|
||
|
||
CSI_CLAR(cap);
|
||
ret = ioctl(fd, VIDIOC_QUERYCAP, (void *)&cap);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 querycap get error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_DBG_LOG("Senor capabilities:V4L2_CAP_VIDEO_CAPTURE = %d\n",cap.capabilities); // 0x01
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_querystd_get(INT32S fd)
|
||
{
|
||
INT32S ret = 0;
|
||
/*struct v4l2_std_id stdId;
|
||
|
||
ret = ioctl(fd, VIDIOC_QUERYSTD, (void *)&stdId);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 querystd get error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
switch(std){
|
||
case V4L2_STD_NTSC:
|
||
CSI_DBG_LOG("current std: NTSC format\r\n");
|
||
break;
|
||
case V4L2_STD_PAL:
|
||
CSI_DBG_LOG("current std: PAL format\r\n");
|
||
break;
|
||
default:
|
||
break;
|
||
}*/
|
||
|
||
//errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_down_smpl_buf_create(INT16U width, INT16U height)
|
||
{
|
||
if((width == 0) ||
|
||
(height == 0)){
|
||
CSI_DBG_LOG("%s:param error!\r\n", __func__);
|
||
return -1;
|
||
}
|
||
|
||
csi_smpl_buf_compare_flag = 0;
|
||
|
||
if(csi_cur_down_smpl_buf == NULL){
|
||
csi_cur_down_smpl_buf = (INT8U *)malloc(width * height);
|
||
}
|
||
|
||
if(csi_last_down_smpl_buf == NULL){
|
||
csi_last_down_smpl_buf = (INT8U *)malloc(width * height);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
INT32S csi_down_smpl_buf_destroy(void)
|
||
{
|
||
if(csi_last_down_smpl_buf){
|
||
free(csi_last_down_smpl_buf);
|
||
csi_last_down_smpl_buf = NULL;
|
||
}
|
||
|
||
if(csi_cur_down_smpl_buf){
|
||
free(csi_cur_down_smpl_buf);
|
||
csi_cur_down_smpl_buf = NULL;
|
||
}
|
||
|
||
csi_smpl_buf_compare_flag = 0;
|
||
|
||
return 0;
|
||
}
|
||
|
||
INT32S csi_down_sampling(INT8U *src, INT8U *dst, INT16U width, INT16U height)
|
||
{
|
||
INT32S nPos, ret = 0;
|
||
INT16U i = 0, j = 0;
|
||
INT8U *p_dst = NULL;
|
||
|
||
if((src == NULL) ||
|
||
(dst == NULL) ||
|
||
(width == 0) ||
|
||
(height == 0)){
|
||
CSI_DBG_LOG("%s:param error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
p_dst = dst;
|
||
for(i = 0; i < height; i += 4){
|
||
nPos = i * width;
|
||
for(j = 0; j < width; j += 4){
|
||
*p_dst++ = src[nPos + j];
|
||
}
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT8U csi_is_move(INT8U *img1, INT8U *img2, INT16U width, INT16U height)
|
||
{
|
||
INT32U sum = 0;
|
||
INT16U i = 0, j = 0;
|
||
INT8U *p_img1 = NULL, *p_img2 = NULL;
|
||
INT8U diff = 0;
|
||
|
||
if((img1 == NULL) ||
|
||
(img2 == NULL) ||
|
||
(width == 0) ||
|
||
(height == 0)){
|
||
CSI_DBG_LOG("%s:param error!\r\n", __func__);
|
||
return 0;
|
||
}
|
||
|
||
p_img1 = img1;
|
||
p_img2 = img2;
|
||
for(i = 0; i < height; i++){
|
||
for(j = 0; j < width; j++){
|
||
diff = abs(*p_img1++ - *p_img2++);
|
||
sum += diff > 20 ? 1 : 0;
|
||
}
|
||
}
|
||
|
||
return sum;
|
||
}
|
||
|
||
INT32S csi_buf_enqueue(CSI_BUF *csiBufAddr)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_buffer v4l2Buf;
|
||
|
||
CSI_CLAR(v4l2Buf);
|
||
|
||
//CSI_DBG_LOG("%s:index = %d, addr = 0x%x\r\n", __func__, csiBufAddr->m_v4l2BufIdx, csiBufAddr->m_v4l2Buf[csiBufAddr->m_v4l2BufIdx].m_addr);
|
||
v4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
v4l2Buf.memory = V4L2_MEMORY_MMAP;
|
||
v4l2Buf.index = csiBufAddr->m_v4l2BufIdx;
|
||
ret = ioctl(csi_v4l2_fd, VIDIOC_QBUF, (void *)&v4l2Buf);
|
||
if(ret != 0)
|
||
{
|
||
|
||
//CSI_DBG_LOG("%s:ioctl v4l2 buf enqueue error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_buf_dequeue(CSI_BUF *csiBufAddr, INT64U *curV4l2BufMsec, INT64U *diffV4l2BufMsec)
|
||
{
|
||
INT32S ret = 0;
|
||
struct v4l2_buffer v4l2Buf;
|
||
fd_set fdSet;
|
||
struct timeval tv;
|
||
static INT32U lastFrmMsec = 0;
|
||
INT32U curFrmMsec = 0, diffFrmMsec = 1;
|
||
//bug14:WJQ:2016-7-5 start
|
||
INT16U sensorWidth = 0, sensorHeight = 0;
|
||
//bug14:WJQ:2016-7-5 end
|
||
INT8S waterMaskStr[64];
|
||
|
||
#if 0
|
||
DATE_TIME dateTime;
|
||
POINT tmpP;
|
||
DATE_TIME_WATER_MARK dateTimeWaterMarkDisp = DATE_TIME_WATER_MARK_MAX;
|
||
#endif
|
||
if( (csiBufAddr == NULL) ||
|
||
(curV4l2BufMsec == NULL) ||
|
||
(diffV4l2BufMsec == NULL)){
|
||
CSI_DBG_LOG("%s:param error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
FD_ZERO(&fdSet);
|
||
FD_SET(csi_v4l2_fd, &fdSet);
|
||
|
||
tv.tv_sec = CSI_SELECT_FRM_TIMEOUT;
|
||
tv.tv_usec = 0;
|
||
ret = select(csi_v4l2_fd + 1, &fdSet, NULL, NULL, &tv);
|
||
if(ret == -1){
|
||
CSI_DBG_LOG("select csi input frm error\r\n");
|
||
ret = -2;
|
||
goto errHdl;
|
||
}else if(ret == 0){
|
||
CSI_DBG_LOG("select csi input frm timeout\r\n");
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_CLAR(v4l2Buf);
|
||
v4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
v4l2Buf.memory = V4L2_MEMORY_MMAP;
|
||
ret = ioctl(csi_v4l2_fd, VIDIOC_DQBUF, (void *)&v4l2Buf);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 buf dequeue error!\r\n", __func__);
|
||
ret = -4;
|
||
goto errHdl;
|
||
}
|
||
|
||
pthread_mutex_lock(&csi_lock);
|
||
if(v4l2Buf.index >= CSI_INPUT_FRM_BUF_MAX){
|
||
CSI_DBG_LOG("%s:ioctl v4l2 buf dequeue index error!\r\n", __func__);
|
||
pthread_mutex_unlock(&csi_lock);
|
||
ret = -5;
|
||
goto errHdl;
|
||
}
|
||
|
||
//CSI_DBG_LOG("%s:index = %d, addr = 0x%x\r\n", __func__, v4l2Buf.index, v4l2Buf.m.offset);
|
||
csiBufAddr->m_v4l2BufIdx = v4l2Buf.index;
|
||
csiBufAddr->m_v4l2Buf[csiBufAddr->m_v4l2BufIdx].m_addr = v4l2Buf.m.offset;
|
||
csi_buf.m_v4l2BufIdx = v4l2Buf.index;
|
||
csiBufAddr->m_buf_start = csi_buf.m_v4l2Buf[v4l2Buf.index].m_addr;
|
||
|
||
#if 0
|
||
// add water mask
|
||
sys_param_date_time_water_mark_get(&dateTimeWaterMarkDisp);
|
||
if(dateTimeWaterMarkDisp == DATE_TIME_WATER_MARK_YES){
|
||
sys_param_date_time_get(&dateTime);
|
||
sys_param_sensor_resoulution_get((INT16U*)&sensorWidth,(INT16U*)&sensorHeight);
|
||
//bug14:WJQ:2016-7-5 start
|
||
snprintf(waterMaskStr, sizeof(waterMaskStr), "%04d-%02d-%02d %02d:%02d:%02d", dateTime.m_date.m_year, dateTime.m_date.m_month, dateTime.m_date.m_day,
|
||
dateTime.m_time.m_hour, dateTime.m_time.m_minute, dateTime.m_time.m_sec);
|
||
tmpP.x = GUI_WATER_MASK_POS_X_PIXEL;
|
||
if((sensorWidth == 640) && (sensorHeight == 480)){
|
||
tmpP.y = GUI_WATER_MASK_VGA_POS_Y_PIXEL;
|
||
}else{
|
||
tmpP.y = GUI_WATER_MASK_720P_POS_Y_PIXEL;
|
||
}
|
||
|
||
if(csi_buf.m_v4l2Buf[csi_buf.m_v4l2BufIdx].m_addr == NULL){
|
||
printf("%s:water mark->invalid csi frame address!\r\n", __func__);
|
||
}else{
|
||
//gui_yuv420p_disp_watermask(&tmpP, waterMaskStr, (INT8U *)(csi_buf.m_v4l2Buf[csi_buf.m_v4l2BufIdx].m_addr));
|
||
gui_yuv420spmb32_disp_watermask(&tmpP, waterMaskStr, (INT8U *)(csi_buf.m_v4l2Buf[csi_buf.m_v4l2BufIdx].m_addr));
|
||
}
|
||
//bug14:WJQ:2016-7-5 end
|
||
}
|
||
#endif
|
||
// gettimeofday(&(v4l2Buf.timestamp), NULL);
|
||
curFrmMsec = v4l2Buf.timestamp.tv_sec * 1000 + v4l2Buf.timestamp.tv_usec / 1000;
|
||
if(lastFrmMsec != 0){
|
||
diffFrmMsec = curFrmMsec - lastFrmMsec;
|
||
}
|
||
lastFrmMsec = curFrmMsec;
|
||
|
||
CSI_DBG_LOG("%s:curFrmMsec = %ums, diffFrmMsec = %ums\r\n", __func__, curFrmMsec, diffFrmMsec);
|
||
|
||
*curV4l2BufMsec = curFrmMsec;
|
||
*diffV4l2BufMsec = diffFrmMsec;
|
||
pthread_mutex_unlock(&csi_lock);
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_buf_request(INT32S fd, INT8U frmNum)
|
||
{
|
||
INT32S ret = 0;
|
||
INT8U i = 0;
|
||
struct v4l2_requestbuffers requestbuffers;
|
||
struct v4l2_buffer v4l2Buf;
|
||
//CSI_BUF csiV4l2Buf;
|
||
|
||
CSI_CLAR(requestbuffers);
|
||
requestbuffers.count = frmNum;
|
||
requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
requestbuffers.memory = V4L2_MEMORY_MMAP;
|
||
ret = ioctl(fd, VIDIOC_REQBUFS, (void *)&requestbuffers);
|
||
if(ret != 0 || requestbuffers.count != CSI_INPUT_FRM_BUF_MAX)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 buf request error!, ret = %d, count = %d\r\n", __func__, ret, requestbuffers.count);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
CSI_DBG_LOG("%s:count = %d\r\n", __func__, requestbuffers.count);
|
||
|
||
pthread_mutex_lock(&csi_lock);
|
||
for(i = 0; i < requestbuffers.count; i++){
|
||
CSI_CLAR(v4l2Buf);
|
||
v4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
v4l2Buf.memory = V4L2_MEMORY_MMAP;
|
||
v4l2Buf.index = i;
|
||
ret = ioctl(fd, VIDIOC_QUERYBUF, (void *)&v4l2Buf);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 buf query error, ret = %d!\r\n", __func__, ret);
|
||
pthread_mutex_unlock(&csi_lock);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
csi_buf.m_v4l2BufIdx = i;
|
||
csi_buf.m_v4l2BufLen = v4l2Buf.length;
|
||
csi_buf.m_v4l2Buf[i].m_addr = (INT32U)mmap(NULL, /* start anywhere */
|
||
v4l2Buf.length,
|
||
PROT_READ | PROT_WRITE, /* required */
|
||
MAP_SHARED, /* recommended */
|
||
fd,
|
||
v4l2Buf.m.offset);
|
||
csi_buf.m_v4l2Buf[i].m_ref = 0;
|
||
if((void *)(csi_buf.m_v4l2Buf[i].m_addr) == MAP_FAILED)
|
||
{
|
||
CSI_DBG_LOG("%s:mmap kernel space alloc buf to user space error!\r\n", __func__);
|
||
pthread_mutex_unlock(&csi_lock);
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
/*CSI_DBG_LOG("%s:m_v4l2BufIdx = %d, m_v4l2BufLen =%d, m_v4l2Buf[%d].m_addr = 0x%x\r\n", __func__,
|
||
csi_buf.m_v4l2BufIdx, csi_buf.m_v4l2BufLen, i, csi_buf.m_v4l2Buf[i].m_addr);*/
|
||
}
|
||
pthread_mutex_unlock(&csi_lock);
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_buf_release(void)
|
||
{
|
||
INT32S ret = 0;
|
||
INT32U i = 0;
|
||
|
||
pthread_mutex_lock(&csi_lock);
|
||
for(i = 0; i < CSI_INPUT_FRM_BUF_MAX; i++) {
|
||
/*
|
||
memset((void *)csi_buf.m_v4l2Buf[i].m_addr, 0x00, (csi_buf.m_v4l2BufLen * 2) / 3); // y
|
||
memset((void *)(csi_buf.m_v4l2Buf[i].m_addr + (csi_buf.m_v4l2BufLen * 2) / 3), 0x80, (csi_buf.m_v4l2BufLen) / 6); // cb
|
||
memset((void *)(csi_buf.m_v4l2Buf[i].m_addr + (csi_buf.m_v4l2BufLen * 5) / 6), 0x80, (csi_buf.m_v4l2BufLen) / 6); // cr
|
||
*/
|
||
ret = munmap((void *)csi_buf.m_v4l2Buf[i].m_addr, csi_buf.m_v4l2BufLen);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("munmap csi frm buf error\r\n");
|
||
pthread_mutex_unlock(&csi_lock);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
}
|
||
|
||
pthread_mutex_unlock(&csi_lock);
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_stream_on(INT32S fd)
|
||
{
|
||
INT32S ret = 0;
|
||
INT8U i = 0;
|
||
enum v4l2_buf_type type;
|
||
CSI_BUF csiBufAddr;
|
||
|
||
for(i = 0; i < CSI_INPUT_FRM_BUF_MAX; i++){
|
||
csiBufAddr.m_v4l2BufIdx = i;
|
||
ret = csi_buf_enqueue(&csiBufAddr);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl v4l2 buf enqueue error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
}
|
||
|
||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
ret = ioctl(fd, VIDIOC_STREAMON, (void *)&type);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl video stream on error!\r\n", __func__);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_stream_off(INT32S fd)
|
||
{
|
||
INT32S ret = 0;
|
||
enum v4l2_buf_type type;
|
||
|
||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
ret = ioctl(fd, VIDIOC_STREAMOFF, (void *)&type);
|
||
if(ret != 0)
|
||
{
|
||
CSI_DBG_LOG("%s:ioctl video stream off error!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
#if 0
|
||
INT32S csi_default_param_set(void)
|
||
{
|
||
INT32S ret = 0;
|
||
|
||
// resolution
|
||
csi_stream_off(csi_v4l2_fd);
|
||
ret = csi_fmt_set(csi_v4l2_fd, 1280, 720, CSI_INPUT_FMT);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:resolution set failed! ret = %d\n", __func__, ret);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
sys_param_sensor_resoulution_set(SENSOR_RESOLUTION_1280X720);
|
||
csi_stream_on(csi_v4l2_fd);
|
||
|
||
// AWB
|
||
sys_param_sensor_awb_set(AWB_AUTO);
|
||
ret = csi_ctrl_set(csi_v4l2_fd, CSI_CTRL_ID_SET_AUTO_AWB, AWB_AUTO);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:awb set failed! ret = %d\n", __func__, ret);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
// AE
|
||
sys_param_sensor_ae_set(AE_0);
|
||
ret = csi_ctrl_set(csi_v4l2_fd, CSI_CTRL_ID_SET_AE, AE_0);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:ae set failed! ret = %d\n", __func__, ret);
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
// LIGHT FREQ
|
||
sys_param_light_freq_mode_set(LIGHT_FREQ_MODE_50_HZ);
|
||
ret = csi_ctrl_set(csi_v4l2_fd, CSI_CTRL_ID_SET_LIGHT_FREQ, LIGHT_FREQ_MODE_50_HZ);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:band set failed! ret = %d\n", __func__, ret);
|
||
ret = -4;
|
||
goto errHdl;
|
||
}
|
||
|
||
// FLIP
|
||
sys_param_image_flip_mode_set(IMAGE_FLIP_MODE_OFF);
|
||
ret = csi_ctrl_set(csi_v4l2_fd, CSI_CTRL_ID_SET_FLIP, IMAGE_FLIP_MODE_OFF);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:band set failed! ret = %d\n", __func__, ret);
|
||
ret = -4;
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
INT32S csi_system_param_set(void)
|
||
{
|
||
INT32S ret = 0;
|
||
INT16U sensorWidth = 1280, sensorHeight = 720;
|
||
|
||
#define V4L2_CID_LIGHT_FREQ (V4L2_CID_BASE+24)
|
||
#define V4L2_CID_FLIP (V4L2_CID_BASE+31)
|
||
#define SW_ROTATE 4
|
||
#define NO_ROTATE 5
|
||
#define V4L2_CID_RESOLUTION (V4L2_CID_BASE+19)
|
||
// sys_param_sensor_resoulution_get(&sensorWidth, &sensorHeight);
|
||
// sys_param_sensor_awb_get(&tmpAwb);
|
||
// sys_param_sensor_ae_get(&tmpAE) ;
|
||
// sys_param_light_freq_mode_get(&tmpLightFreq);
|
||
// sys_param_image_flip_mode_get(&tmpImgFlipMode);
|
||
|
||
// Resolution Set
|
||
csi_stream_off(csi_v4l2_fd);
|
||
ret = csi_fmt_set(csi_v4l2_fd, sensorWidth, sensorHeight, CSI_INPUT_FMT);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:resolution set failed! ret = %d\n", __func__, ret);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
csi_stream_on(csi_v4l2_fd);
|
||
|
||
// AWB Set
|
||
ret = csi_ctrl_set(csi_v4l2_fd, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, V4l2_API_WHITE_BALANCE_AUTO);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:awb set failed! ret = %d\n", __func__, ret);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
// AE Set
|
||
ret = csi_ctrl_set(csi_v4l2_fd, V4L2_CID_EXPOSURE, 0);
|
||
if(ret != 0){
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
// Light Freq Set
|
||
ret = csi_ctrl_set(csi_v4l2_fd, V4L2_CID_LIGHT_FREQ, V4l2_API_LIGHT_FREQ_50Hz);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:band set failed! ret = %d\n", __func__, ret);
|
||
ret = -4;
|
||
goto errHdl;
|
||
}
|
||
|
||
// Image Flip Set
|
||
ret = csi_ctrl_set(csi_v4l2_fd, V4L2_CID_FLIP, NO_ROTATE);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:flip set failed! ret = %d\n", __func__, ret);
|
||
ret = -5;
|
||
goto errHdl;
|
||
}
|
||
|
||
|
||
ret = csi_ctrl_set(csi_v4l2_fd, V4L2_CID_RESOLUTION, V4l2_API_RESOLUTION_720P);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:resolution set failed! ret = %d\n", __func__, ret);
|
||
ret = -5;
|
||
goto errHdl;
|
||
}
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_open(INT8S *path)
|
||
{
|
||
INT32S csiFd = 0;
|
||
|
||
if(path == NULL){
|
||
CSI_DBG_LOG("%s:param error!\r\n", __func__);
|
||
csiFd = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
csiFd = open(path, O_RDWR | O_NONBLOCK, 0);
|
||
if(csiFd == -1){
|
||
CSI_DBG_LOG("%s:open csi handle error!\r\n", __func__);
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return csiFd;
|
||
}
|
||
|
||
INT32S csi_close(INT32S csiFd)
|
||
{
|
||
INT32S ret = 0;
|
||
|
||
ret = close(csiFd);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:close csi handle failed!\r\n", __func__);
|
||
goto errHdl;
|
||
}
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_init(void)
|
||
{
|
||
INT32S ret = 0;
|
||
|
||
pthread_mutex_init(&csi_lock, NULL);
|
||
|
||
csi_v4l2_fd = csi_open(CSI_DEV_NAME);
|
||
if(csi_v4l2_fd == -1){
|
||
CSI_DBG_LOG("%s:open csi handle is not exist!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
ret = csi_input_set(csi_v4l2_fd, CSI_INPUT_ID_OV5640);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:set csi input error!\r\n", __func__);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
ret = csi_fmt_set(csi_v4l2_fd, CSI_WIDTH_MAX, CSI_HEIGHT_MAX, CSI_INPUT_FMT);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:set csi resolution and format error!\r\n", __func__);
|
||
ret = -3;
|
||
goto errHdl;
|
||
}
|
||
|
||
ret = csi_buf_request(csi_v4l2_fd, CSI_INPUT_FRM_BUF_MAX);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:request csi buf error!\r\n", __func__);
|
||
ret = -4;
|
||
}
|
||
/*ret = csi_system_param_set();
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:restore csi system param set error!\r\n", __func__);
|
||
ret = -5;
|
||
}*/
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
INT32S csi_uninit(void)
|
||
{
|
||
INT32S ret = 0;
|
||
|
||
ret = csi_buf_release();
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:free csi frame buffer failed!\r\n", __func__);
|
||
ret = -1;
|
||
goto errHdl;
|
||
}
|
||
|
||
ret = csi_close(csi_v4l2_fd);
|
||
if(ret != 0){
|
||
CSI_DBG_LOG("%s:close csi handle failed!\r\n", __func__);
|
||
ret = -2;
|
||
goto errHdl;
|
||
}
|
||
|
||
pthread_mutex_destroy(&csi_lock);
|
||
|
||
errHdl:
|
||
return ret;
|
||
}
|
||
|
||
#endif // #if MODULE_CSI_COMPILE_CFG == 1
|