一: linux驱动层
1. 通讯方式I2C驱动注册:
a: arch/arm/mach-mx5/mx53_xx.c
/*
声明s5k5bbgx的IIC 资源
*/
- <span style="font-size:16px;">static int mxc_camera2_pwdn(int pwdn)
- {
- if (pwdn)
- gpio_direction_output(MX53_HMS_CAMERA2_PWN, 1);
- else
- gpio_direction_output(MX53_HMS_CAMERA2_PWN, 0);
- return 0;
- }
-
- static struct mxc_camera_platform_data camera2_data = {
- .mclk = 24000000,
- .csi = 0,
- .pwdn = mxc_camera2_pwdn,
- };
-
- static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
-
- {
- .type = "s5k5bbgx",
- .addr = 0x2d,
-
- .platform_data = (void *)&camera2_data,
- },
-
- }
-
- </span>
- <span style="font-size:16px;">
-
-
- static void __init mxc_board_init(void)
- {
- i2c_register_board_info(0, mxc_i2c0_board_info,
- ARRAY_SIZE(mxc_i2c0_board_info));
- }</span>
b: driver/media/video/capture/xx_cam_2M.c
/*
* 注册IIC驱动
*/
- <span style="font-size:16px;">static struct i2c_client *s5k5bbgx_i2c_client = NULL;
-
-
- static const struct i2c_device_id s5k5bbgx_id[] = {
- {"s5k5bbgx", 0},
- {},
- };
-
- MODULE_DEVICE_TABLE(i2c, s5k5bbgx_id);
-
- static struct 2055_i2c_drvier {
- .driver = {
- .owner = THIS_MODULE,
- .name = "s5k5bbgx",
- },
- .probe = s5k5bbgx_probe,
- .remove = s5k5bbgx_remove,
- .id_table = s5k5bbgx_id,
-
-
- };
-
-
-
-
-
-
- static __init int s5k5bbgx_init(void)
- {
- U8 err;
- err = i2c_add_driver(s5k5bbgx_i2c_driver);
- return err;
- }
- static int s5k5bbgx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- s5k5bbgx_i2c_client = client;
-
- return 0;
- }
-
-
-
- static s32 s5k5bbgx_read_reg(u16 reg, u16 *val)
- {
- u8 au8RegBuf[2] = {0};
- u8 data[2] = {0};
-
- au8RegBuf[0] = reg >> 8;
- au8RegBuf[1] = reg & 0xff;
-
- if (2 != i2c_master_send(s5k5bbgx_i2c_client, au8RegBuf, 2)) {
- pr_err("%s:write reg error:reg=%x\n",
- __func__, reg);
- return -1;
- }
-
- if (2 != i2c_master_recv(s5k5bbgx_i2c_client, data, 2)) {
- pr_err("%s:read reg error:reg=0x%04x\n",
- __func__, reg);
- return -2;
- }
-
- *val = (data[0] << 8) | data[1];
-
- return 0;
- }
-
-
- static s32 s5k5bbgx_write_reg(u16 cammand, u16 val)
- {
- u8 au8Buf[4] = {0};
-
- au8Buf[0] = cammand >> 8;
- au8Buf[1] = cammand & 0xff;
- au8Buf[2] = val >> 8;
- au8Buf[3] = val & 0xff;
-
- if (4 != i2c_master_send(s5k5bbgx_i2c_client, au8Buf, 4)) {
- pr_err("%s:write cammand error:cammand=0x%04x,val=0x%04x\n",
- __func__, cammand, val);
- return -1;
- }
-
- return 0;
- }
- <strong>
- </strong></span>
至此IIC注册完毕
b: 注册 v4l2 slave device:
- <span style="font-size:16px;">
-
-
- struct sensor {
- const struct mxc_camera_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_captureparm streamcap;
- bool on;
-
-
- int brightness;
- int hue;
- int contrast;
- int saturation;
- int red;
- int green;
- int blue;
- int ae_mode;
-
- u32 mclk;
- int csi;
- }s5k5bbgx_data;
-
-
-
-
- static struct v4l2_int_ioctl_desc s5k5bbgx_ioctl_desc[] = {
-
- {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
- {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
-
- };
-
-
- static struct v4l2_int_slave s5k5bbgx_slave = {
- .ioctls = s5k5bbgx_ioctl_desc,
- .num_ioctls = ARRAY_SIZE(s5k5bbgx_ioctl_desc),
- };
-
-
- static struct v4l2_int_device s5k5bbgx_int_device = {
- .module = THIS_MODULE,
- .name = "s5k5bbgx",
- .type = v4l2_int_type_slave,
- .u = {
- .slave = &s5k5bbgx_slave,
- },
- };
-
-
-
-
-
-
-
-
-
- static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
- {
- struct sensor *sensor = s->priv;
- struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
- u32 tgt_fps;
- enum s5k5bbgx_frame_rate frame_rate;
- int ret = 0;
-
-
- if (camera_plat->pwdn)
- camera_plat->pwdn(0);
-
- switch (a->type) {
-
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-
-
-
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- pr_debug(" type is not " \
- "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
- a->type);
- ret = -EINVAL;
- break;
-
- default:
- pr_debug(" type is unknown - %d\n", a->type);
- ret = -EINVAL;
- break;
- }
-
- return ret;
- }
-
-
-
-
-
-
-
-
-
- static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
- {
- int retval = 0;
-
- pr_debug("In s5k5bbgx:ioctl_s_ctrl %d\n",
- vc->id);
-
- switch (vc->id) {
- case V4L2_CID_BRIGHTNESS:
- break;
- case V4L2_CID_CONTRAST:
- break;
- case V4L2_CID_SATURATION:
- break;
- case V4L2_CID_HUE:
- break;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- break;
- default:
- retval = -EPERM;
- break;
- }
-
- return retval;
- }
-
-
-
- static int s5k5bbgx_probe(strct i2c_client *client, const struct i2c_device_id *id)
- {
- s5k5bbgx_int_device.priv = &s5k5bbgx_data;
- retval = v4l2_int_device_register(&s5k5bbgx_int_device);
- }
- </span>
v4l2 slave device 注册完毕
c: s5k5bbgx 初始化和操作
- <span style="font-size:16px;">static int s5k5bbgx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
-
-
-
-
- s5k5bbgx_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-
- s5k5bbgx_data.pix.width = 800;
- s5k5bbgx_data.pix.height = 600;
- s5k5bbgx_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
- V4L2_CAP_TIMEPERFRAME;
- s5k5bbgx.streamcap.capturemode = 0;
- s5k5bbgx_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
- s5k5bbgx_data.streamcap.timeperframe.numerator = 1;
-
- }
- static int s5k5bbgx_init_mode(enum s5k5bbgx_frame_rate frame_rate,
- enum s5k5bbgx_mode mode)
- {
- struct reg_value *pModeSetting = NULL;
- s32 i = 0;
- s32 iModeSettingArySize = 0;
- register u32 Delay_ms = 0;
- register u16 RegAddr = 0;
- register u8 Mask = 0;
- register u16 Val = 0;
- register u8 u8Val = 0;
- u8 RegVal = 0;
- int retval = 0;
-
-
- pModeSetting = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_ptr;
- iModeSettingArySize = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_size;
- s5k5bbgx_data.pix.width = s5k5bbgx_mode_info_data[frame_rate][mode].width;
- s5k5bbgx_data.pix.height = s5k5bbgx_mode_info_data[frame_rate][mode].height;
-
-
-
- for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
- Delay_ms = pModeSetting->u32Delay_ms;
- RegAddr = pModeSetting->u16RegAddr;
- Val = pModeSetting->u16Val;
- Mask = pModeSetting->u8Mask;
- if (Mask) {
- RegVal &= ~(u8)Mask;
- Val &= Mask;
- Val |= RegVal;
- }
- retval = s5k5bbgx_write_reg(RegAddr, Val);
- if (retval < 0)
- goto err;
-
- if (Delay_ms)
- msleep(Delay_ms);
- }
- }
-
- struct s5k5ggbx_set s5k5ggbx_set_data[12] = {
- {preview, ARRAY_SIZE(preview)},
- {record, ARRAY_SIZE(record)},
- {night, ARRAY_SIZE(night)},
- {capture, ARRAY_SIZE(capture)},
- {normal, ARRAY_SIZE(normal)},
- {mono, ARRAY_SIZE(mono)},
- {negative, ARRAY_SIZE(negative)},
- {sepia, ARRAY_SIZE(sepia)},
- {Auto, ARRAY_SIZE(Auto)},
- {incandescent, ARRAY_SIZE(incandescent)},
- {daylight, ARRAY_SIZE(daylight)},
- {flourescent, ARRAY_SIZE(flourescent)}
- };
-
-
-
-
- static int s5k5ggbx_set_code(int index)
- {
- struct reg_value *p = NULL;
- s32 i = 0;
- s32 size = 0;
- int retval;
- register u32 Delay_ms = 0;
- register u16 RegAddr = 0;
- register u16 Val = 0;
-
- p = s5k5ggbx_set_data[index].init_data_ptr;
- size = s5k5ggbx_set_data[index].init_data_size;
-
- for (i = 0; i < size; ++i, ++p) {
- Delay_ms = p->u32Delay_ms;
- RegAddr = p->u16RegAddr;
- Val = p->u16Val;
-
- retval = s5k5bbgx_write_reg(RegAddr, Val);
- if (retval < 0)
- return retval;
-
- if (Delay_ms)
- msleep(Delay_ms);
-
- }
-
- return 0;
- }
-
-
- static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
- {
- switch (a->type) {
-
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-
- if ((timeperframe->numerator == 0) ||
- (timeperframe->denominator == 0)) {
- timeperframe->denominator = DEFAULT_FPS;
- timeperframe->numerator = 1;
- }
-
- tgt_fps = timeperframe->denominator /
- timeperframe->numerator;
-
- if (tgt_fps > MAX_FPS) {
- timeperframe->denominator = MAX_FPS;
- timeperframe->numerator = 1;
- } else if (tgt_fps < MIN_FPS) {
- timeperframe->denominator = MIN_FPS;
- timeperframe->numerator = 1;
- }
-
-
- tgt_fps = timeperframe->denominator /
- timeperframe->numerator;
-
-
- tgt_fps = timeperframe->denominator /
- timeperframe->numerator;
-
- if (tgt_fps == 15)
- frame_rate = ov2655_15_fps;
- else if (tgt_fps == 30)
- frame_rate = ov2655_30_fps;
- else if (tgt_fps == 7)
- frame_rate = ov2655_7p5_fps;
- else {
- pr_err(" The camera frame rate is not supported!\n");
- return -EINVAL;
- }
-
- sensor->streamcap.timeperframe = *timeperframe;
- sensor->streamcap.capturemode = (u32)a->parm.capture.capturemode;
- printk("\n%s, frame_rate = %d, sensor->streamcap.capturemode = %d\n", __func__, frame_rate, sensor->streamcap.capturemode);
- if (sensor->streamcap.capturemode == 2)
- {
- s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);
- s5k5ggbx_set_code(0);
- }
- else if (sensor->streamcap.capturemode == 4)
- {
- s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);
- s5k5ggbx_set_code(3);
- }
- else if (sensor->streamcap.capturemode == 1)
- {
- s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);
- s5k5ggbx_set_code(1);
- }
-
-
- break;
-
- }
-
- }
-
-
- </span>
二,V4L2 capture应用
1.接口
- <span style="font-size:16px;">namespace android{
-
- class V4l2CapDeviceBase : public CaptureDeviceInterface{
- public:
-
- virtual CAPTURE_DEVICE_ERR_RET SetDevName(char * deviceName);
- virtual CAPTURE_DEVICE_ERR_RET GetDevName(char * deviceName);
- virtual CAPTURE_DEVICE_ERR_RET DevOpen();
- virtual CAPTURE_DEVICE_ERR_RET EnumDevParam(DevParamType devParamType, void *retParam);
- virtual CAPTURE_DEVICE_ERR_RET DevSetCtrl(int id,int value);
- virtual CAPTURE_DEVICE_ERR_RET DevSetConfig(struct capture_config_t *pCapcfg);
- virtual CAPTURE_DEVICE_ERR_RET DevAllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);
- virtual CAPTURE_DEVICE_ERR_RET DevPrepare();
- virtual CAPTURE_DEVICE_ERR_RET DevStart();
- virtual CAPTURE_DEVICE_ERR_RET DevDequeue(unsigned int *pBufQueIdx);
- virtual CAPTURE_DEVICE_ERR_RET DevStop();
- virtual CAPTURE_DEVICE_ERR_RET DevDeAllocate();
- virtual CAPTURE_DEVICE_ERR_RET DevClose();
-
- protected:
-
- V4l2CapDeviceBase();
- virtual ~V4l2CapDeviceBase();
- virtual CAPTURE_DEVICE_ERR_RET V4l2Open();
- virtual CAPTURE_DEVICE_ERR_RET V4l2EnumParam(DevParamType devParamType, void *retParam);
- virtual CAPTURE_DEVICE_ERR_RET V4l2EnumFmt(void *retParam);
- virtual CAPTURE_DEVICE_ERR_RET V4l2EnumSizeFps(void *retParam);
- virtual CAPTURE_DEVICE_ERR_RET V4l2SetConfig(struct capture_config_t *pCapcfg);
- virtual CAPTURE_DEVICE_ERR_RET V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);
- virtual CAPTURE_DEVICE_ERR_RET V4l2Prepare();
- virtual CAPTURE_DEVICE_ERR_RET V4l2Start();
- virtual CAPTURE_DEVICE_ERR_RET V4l2Dequeue(unsigned int *pBufQueIdx);
- virtual CAPTURE_DEVICE_ERR_RET V4l2Queue(unsigned int BufQueIdx);
- virtual CAPTURE_DEVICE_ERR_RET V4l2Stop();
- virtual CAPTURE_DEVICE_ERR_RET V4l2DeAlloc();
- virtual CAPTURE_DEVICE_ERR_RET V4l2Close();
- virtual CAPTURE_DEVICE_ERR_RET V4l2ConfigInput(struct capture_config_t *pCapcfg);
- virtual CAPTURE_DEVICE_ERR_RET V4l2GetCaptureMode(struct capture_config_t *pCapcfg, unsigned int *pMode);
- virtual CAPTURE_DEVICE_ERR_RET V4l2SetRot(struct capture_config_t *pCapcfg);
-
- char mCaptureDeviceName[CAMAERA_FILENAME_LENGTH];
- char mInitalDeviceName[CAMAERA_SENSOR_LENGTH];
- int mCameraDevice;
- unsigned int mFmtParamIdx;
- unsigned int mSizeFPSParamIdx;
- unsigned int mRequiredFmt;
- unsigned int mBufQueNum;
- int mQueuedBufNum;
- DMA_BUFFER mCaptureBuffers[MAX_CAPTURE_BUF_QUE_NUM];
- struct capture_config_t mCapCfg;
-
- };
- };
- </span>
2. 经典的调用流程。
具体解析可以看 http://www.linuxidc.com/Linux/2011-03/33022.htm
a. open device /dev/video16
b . VIDIOC_ENUM_FMT : get video capture supported format
struct v4l2_fmtdesc fmt;
ioctl(dev, VIDIOC_ENUM_FMT, &fmt))
c. VIDIOC_QUERYCAP , get the capture ability
struct v4l2_capability cap;
iret = ioctl(fd_usbcam, VIDIOC_QUERYCAP, &cap);
d. VIDIOC_S_FMT , set parameter
struct v4l2_format tv4l2_format;
tv4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tv4l2_format.fmt.pix.width = img_width;
tv4l2_format.fmt.pix.height = img_height;
tv4l2_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
tv4l2_format.fmt.pix.field = V4L2_FIELD_INTERLACED;
iret = ioctl(fd_usbcam, VIDIOC_S_FMT, &tv4l2_format);
e. VIDIOC_REQBUFS : get buffer
// Request buffers
struct v4l2_requestbuffers reqbuf;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
reqbuf.count = BUFFER_COUNT;
ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);
if(ret < 0) {
LOG("VIDIOC_REQBUFS failed (%d)\n", ret);
return ret;
}
f. VIDIOC_QUERYBUF
struct v4l2_buffer buf;
for(i=0; i // Query buffer
buf.index = i;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
if(ret < 0) {
LOG("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
return ret;
}
// mmap buffer
framebuf[i].length = buf.length;
framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if (framebuf[i].start == MAP_FAILED) {
LOG("mmap (%d) failed: %s\n", i, strerror(errno));
return -1;
}
g. VIDIOC_QBUF
struct v4l2_buffer tV4L2buf;
memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
tV4L2buf.index = i; //(指定)要投放到视频输入队列中的内核空间视频缓冲区的编号;
iret = ioctl(fd_usbcam, VIDIOC_QBUF, &tV4L2buf);
H. VIDIOC_STREAMON
enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fd_set fds ;
struct timeval tv;
iret = ioctl(fd_usbcam, VIDIOC_STREAMON, &v4l2type);
i. VIDIOC_DQBUF
struct v4l2_buffer tV4L2buf;
memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));
tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
tV4L2buf.memory = V4L2_MEMORY_MMAP;
iret = ioctl(fd_usbcam, VIDIOC_DQBUF, &tV4L2buf);
j. VIDIOC_QBUF VIDIOC_DQBUF VIDIOC_QBUF ...... (read data)
k. VIDIOC_STREAMOFF
enum v4l2_buf_type v4l2type;
v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
iret = ioctl(fd_usbcam, VIDIOC_STREAMOFF, &v4l2type);
3. android 上的实际实现:
与上面的大同小异,贴出两个函数
- CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2Open(){
- CAMERA_HAL_LOG_FUNC;
- int fd = 0, i, j, is_found = 0;
- const char *flags[] = {"uncompressed", "compressed"};
-
- char dev_node[CAMAERA_FILENAME_LENGTH];
- DIR *v4l_dir = NULL;
- struct dirent *dir_entry;
- struct v4l2_capability v4l2_cap;
- struct v4l2_fmtdesc vid_fmtdesc;
- struct v4l2_frmsizeenum vid_frmsize;
- CAPTURE_DEVICE_ERR_RET ret = CAPTURE_DEVICE_ERR_NONE;
-
- if(mCameraDevice > 0)
- return CAPTURE_DEVICE_ERR_ALRADY_OPENED;
- else if (mCaptureDeviceName[0] != '#'){
- CAMERA_HAL_LOG_RUNTIME("already get the device name %s", mCaptureDeviceName);
- mCameraDevice = open(mCaptureDeviceName, O_RDWR, O_NONBLOCK);
- if (mCameraDevice < 0)
- return CAPTURE_DEVICE_ERR_OPEN;
- }
- else{
- CAMERA_HAL_LOG_RUNTIME("deviceName is %s", mInitalDeviceName);
- v4l_dir = opendir("/sys/class/video4linux");
- if (v4l_dir){
- while((dir_entry = readdir(v4l_dir))) {
- memset((void *)dev_node, 0, CAMAERA_FILENAME_LENGTH);
- if(strncmp(dir_entry->d_name, "video", 5))
- continue;
- sprintf(dev_node, "/dev/%s", dir_entry->d_name);
- if ((fd = open(dev_node, O_RDWR, O_NONBLOCK)) < 0)
- continue;
- CAMERA_HAL_LOG_RUNTIME("dev_node is %s", dev_node);
- if(ioctl(fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0 ) {
- close(fd);
- continue;
- } else if ((strstr((char *)v4l2_cap.driver, mInitalDeviceName) != 0) &&
- (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
- is_found = 1;
- strcpy(mCaptureDeviceName, dev_node);
- CAMERA_HAL_LOG_RUNTIME("device name is %s", mCaptureDeviceName);
- break;
- } else
- close(fd);
- }
- }
- if (fd > 0)
- mCameraDevice = fd;
- else{
- CAMERA_HAL_ERR("The device name is not correct or the device is error");
- return CAPTURE_DEVICE_ERR_OPEN;
- }
- }
- return ret;
- }
- CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum){
- unsigned int i;
- struct v4l2_buffer buf;
- enum v4l2_buf_type type;
- struct v4l2_requestbuffers req;
- int BufQueNum;
-
- CAMERA_HAL_LOG_FUNC;
- if (mCameraDevice <= 0 || DevBufQue == NULL || pBufQueNum == NULL || *pBufQueNum == 0){
- return CAPTURE_DEVICE_ERR_BAD_PARAM;
- }
-
- mBufQueNum = *pBufQueNum;
-
- memset(&req, 0, sizeof (req));
- req.count = mBufQueNum;
- req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- req.memory = V4L2_MEMORY_MMAP;
- if (ioctl(mCameraDevice, VIDIOC_REQBUFS, &req) < 0) {
- CAMERA_HAL_ERR("v4l_capture_setup: VIDIOC_REQBUFS failed\n");
- return CAPTURE_DEVICE_ERR_SYS_CALL;
- }
-
- *pBufQueNum = mBufQueNum = req.count;
-
- for (i = 0; i < mBufQueNum; i++) {
- memset(&buf, 0, sizeof (buf));
- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf.index = i;
- if (ioctl(mCameraDevice, VIDIOC_QUERYBUF, &buf) < 0) {
- CAMERA_HAL_ERR("VIDIOC_QUERYBUF error\n");
- return CAPTURE_DEVICE_ERR_SYS_CALL;
- } else {
- CAMERA_HAL_LOG_RUNTIME("VIDIOC_QUERYBUF ok\n");
- }
-
- mCaptureBuffers[i].length = DevBufQue[i].length= buf.length;
- mCaptureBuffers[i].phy_offset = DevBufQue[i].phy_offset = (size_t) buf.m.offset;
- mCaptureBuffers[i].virt_start = DevBufQue[i].virt_start = (unsigned char *)mmap (NULL, mCaptureBuffers[i].length,
- PROT_READ | PROT_WRITE, MAP_SHARED, mCameraDevice, mCaptureBuffers[i].phy_offset);
- memset(mCaptureBuffers[i].virt_start, 0xFF, mCaptureBuffers[i].length);
- CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].length = %d\n", i, mCaptureBuffers[i].length);
- CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].phy_offset = 0x%x\n", i, mCaptureBuffers[i].phy_offset);
- CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].virt_start = 0x%x\n", i, (unsigned int)(mCaptureBuffers[i].virt_start));
- }
-
- return CAPTURE_DEVICE_ERR_NONE;
- }