1 2 3#define BUFFER_COUNT 4 4#define CLEAR(x) memset(&(x), 0, sizeof(x)) 5#define FMT_NUM_PLANES 1 6 7struct buffer { 8 void *start; 9 size_t length; 10 int export_fd; 11 int sequence; 12}; 13 14 15enum v4l2_buf_type g_buf_type; 16struct buffer *g_buffers; 17unsigned int g_n_buffers; 18 19static int g_ispfd = -1; 20 21static int xioctl(int fh, int request, void *arg) 22{ 23 int r; 24 do { 25 r = ioctl(fh, request, arg); 26 } while (-1 == r && EINTR == errno && g_aiq_quit == 0); 27 return r; 28} 29 30static void errno_exit(const char *s) 31{ 32 printf("%s: %s error %d, %s\n", g_sns_name, s, errno, strerror(errno)); 33} 34 35static void init_mmap(void) 36{ 37 struct v4l2_requestbuffers req; 38 CLEAR(req); 39 40 req.count = BUFFER_COUNT; 41 req.type = g_buf_type; 42 req.memory = V4L2_MEMORY_MMAP; 43 44 struct buffer *tmp_buffers = NULL; 45 46 if (-1 == xioctl(g_ispfd, VIDIOC_REQBUFS, &req)) { 47 if (EINVAL == errno) { 48 printf("%s: %s does not support " 49 "memory mapping\n" ,g_sns_name ,VIDEO_DEVNAME); 50 } else { 51 errno_exit("VIDIOC_REQBUFS"); 52 } 53 } 54 55 if (req.count < 2) { 56 printf("%s: Insufficient buffer memory on %s\n",g_sns_name, 57 VIDEO_DEVNAME); 58 } 59 60 tmp_buffers = (struct buffer*)calloc(req.count, sizeof(struct buffer)); 61 62 if (!tmp_buffers) { 63 printf("%s: Out of memory\n",g_sns_name); 64 } 65 66 g_buffers = tmp_buffers; 67 unsigned int n_buffers; 68 69 for (n_buffers = 0; n_buffers < req.count; n_buffers++ ) { 70 struct v4l2_buffer buf; 71 struct v4l2_plane planes[FMT_NUM_PLANES]; 72 CLEAR(buf); 73 CLEAR(planes); 74 75 buf.type = g_buf_type; 76 buf.memory = V4L2_MEMORY_MMAP; 77 buf.index = n_buffers; 78 79 if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) { 80 buf.m.planes = planes; 81 buf.length = FMT_NUM_PLANES; 82 } 83 84 if (-1 == xioctl(g_ispfd, VIDIOC_QUERYBUF, &buf)) 85 errno_exit("VIDIOC_QUERYBUF"); 86 87 if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) { 88 tmp_buffers[n_buffers].length = buf.m.planes[0].length; 89 tmp_buffers[n_buffers].start = 90 mmap(NULL /* start anywhere */, 91 buf.m.planes[0].length, 92 PROT_READ | PROT_WRITE /* required */, 93 MAP_SHARED /* recommended */, 94 g_ispfd, buf.m.planes[0].m.mem_offset); 95 } else { 96 tmp_buffers[n_buffers].length = buf.length; 97 tmp_buffers[n_buffers].start = 98 mmap(NULL /* start anywhere */, 99 buf.length, 100 PROT_READ | PROT_WRITE /* required */, 101 MAP_SHARED /* recommended */, 102 g_ispfd, buf.m.offset); 103 } 104 105 if (MAP_FAILED == tmp_buffers[n_buffers].start) 106 errno_exit("mmap"); 107 108 // export buf dma fd 109 struct v4l2_exportbuffer expbuf; 110 xcam_mem_clear (expbuf); 111 expbuf.type = g_buf_type; 112 expbuf.index = n_buffers; 113 expbuf.flags = O_CLOEXEC; 114 if (xioctl(g_ispfd, VIDIOC_EXPBUF, &expbuf) < 0) { 115 errno_exit("get dma buf failed\n"); 116 } else { 117 printf("%s: get dma buf(%d)-fd: %d\n",g_sns_name, n_buffers, expbuf.fd); 118 } 119 tmp_buffers[n_buffers].export_fd = expbuf.fd; 120 } 121 g_n_buffers = n_buffers; 122} 123 124void rkisp_init_device(int w, int h) 125{ 126 struct v4l2_capability cap; 127 struct v4l2_format fmt; 128 struct v4l2_selection selection; 129 130 if (-1 == xioctl(g_ispfd, VIDIOC_QUERYCAP, &cap)) { 131 if (EINVAL == errno) { 132 printf("%s: %s is no V4L2 device\n",g_sns_name, VIDEO_DEVNAME); 133 } else { 134 errno_exit("VIDIOC_QUERYCAP"); 135 } 136 } 137 138 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && 139 !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) { 140 printf("%s: %s is not a video capture device, capabilities: %x\n", 141 g_sns_name, VIDEO_DEVNAME, cap.capabilities); 142 } 143 144 if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 145 printf("%s: %s does not support streaming i/o\n",g_sns_name, 146 VIDEO_DEVNAME); 147 } 148 149 if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { 150 g_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 151 CLEAR(fmt); 152 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 153 fmt.fmt.pix.width = w; 154 fmt.fmt.pix.height = h; 155 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; 156 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 157 fmt.fmt.pix.quantization = V4L2_QUANTIZATION_FULL_RANGE; 158 } else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) { 159 g_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 160 CLEAR(fmt); 161 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 162 fmt.fmt.pix_mp.width = w; 163 fmt.fmt.pix_mp.height = h; 164 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 165 fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED; 166 fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE; 167 } 168 169 if (-1 == xioctl(g_ispfd, VIDIOC_S_FMT, &fmt)) 170 errno_exit("VIDIOC_S_FMT"); 171 172 memset(&selection, 0, sizeof(selection)); 173 174 selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 175 selection.target = V4L2_SEL_TGT_CROP; 176 selection.flags = 0; 177 selection.r.left = 0; 178 selection.r.top = 0; 179 selection.r.width = w; 180 selection.r.height = h; 181 182 if (-1 == xioctl(g_ispfd, VIDIOC_S_SELECTION, &selection)) 183 errno_exit("VIDIOC_S_SELECTION"); 184 185 init_mmap(); 186} 187 188void rkisp_uninit_device(void) 189{ 190 unsigned int i; 191 192 for (i = 0; i < g_n_buffers; ++i) { 193 if (-1 == munmap(g_buffers[i].start, g_buffers[i].length)) 194 errno_exit("munmap"); 195 196 close(g_buffers[i].export_fd); 197 } 198 199 free(g_buffers); 200} 201 202void rkisp_start_capturing(void) 203{ 204 unsigned int i; 205 enum v4l2_buf_type type; 206 207 for (i = 0; i < g_n_buffers; ++i) { 208 struct v4l2_buffer buf; 209 210 CLEAR(buf); 211 buf.type = g_buf_type; 212 buf.memory = V4L2_MEMORY_MMAP; 213 buf.index = i; 214 215 if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) { 216 struct v4l2_plane planes[FMT_NUM_PLANES]; 217 218 buf.m.planes = planes; 219 buf.length = FMT_NUM_PLANES; 220 } 221 if (-1 == xioctl(g_ispfd, VIDIOC_QBUF, &buf)) 222 errno_exit("VIDIOC_QBUF"); 223 } 224 type = g_buf_type; 225 printf("%s:-------- stream on output -------------\n",g_sns_name); 226 if (-1 == xioctl(g_ispfd, VIDIOC_STREAMON, &type)) 227 errno_exit("VIDIOC_STREAMON"); 228} 229 230void rkisp_stop_capturing(void) 231{ 232 enum v4l2_buf_type type; 233 234 type = g_buf_type; 235 if (-1 == xioctl(g_ispfd, VIDIOC_STREAMOFF, &type)) 236 errno_exit("VIDIOC_STREAMOFF"); 237} 238 239static int write_yuv_to_file(const void *p, 240 int size, int sequence) 241{ 242 char file_name[64] = {0}; 243 244 snprintf(file_name, sizeof(file_name), 245 "/tmp/frame%d.yuv", sequence); 246 FILE *fp = fopen(file_name, "wb"); 247 if (fp == NULL) { 248 printf("fopen yuv file %s failed!\n", file_name); 249 return -1; 250 } 251 252 fwrite(p, size, 1, fp); 253 fflush(fp); 254 255 if (fp) { 256 fclose(fp); 257 fp = NULL; 258 } 259 printf("write_yuv_to_file %s %d!\n", file_name, size); 260 return 0; 261} 262 263 264static void* isp_thread(void* args) { 265 struct v4l2_buffer buf = {0}; 266 int i, bytesused; 267 int cnt = 0; 268 269/* 270 rk_aiq_gamma_attr_t gama_attr; 271 gama_attr.atrrV30.mode = RK_AIQ_GAMMA_MODE_OFF; 272 gama_attr.atrrV21.mode = RK_AIQ_GAMMA_MODE_OFF; 273 rk_aiq_user_api2_agamma_SetAttrib(g_aiq_ctx, gama_attr); 274 275 aeMeasAreaType_t aeMeasArea; 276 memset(&aeMeasArea, 0, sizeof(aeMeasAreaType_t)); 277 rk_aiq_uapi2_setBLCMode(g_aiq_ctx, false, aeMeasArea); 278 279 280 rk_aiq_dpcc_attrib_V20_t dpcc_attr; 281 memset(&dpcc_attr, 0, sizeof(rk_aiq_dpcc_attrib_V20_t)); 282 rk_aiq_user_api2_adpcc_SetAttrib(g_aiq_ctx, &dpcc_attr); 283 284 rk_aiq_cpsl_cfg_t cpsl_cfg; 285 memset(&cpsl_cfg, 0, sizeof(rk_aiq_cpsl_cfg_t)); 286 rk_aiq_uapi2_sysctl_setCpsLtCfg(g_aiq_ctx, &cpsl_cfg); 287 288 //acp_attrib_t acp_addr; 289 //memset(&acp_addr, 0, sizeof(acp_attrib_t)); 290 //rk_aiq_user_api2_acp_SetAttrib(g_aiq_ctx, acp_addr); 291 292 rk_aiq_lsc_attrib_t lsc_attr; 293 memset(&lsc_attr, 0, sizeof(rk_aiq_lsc_attrib_t)); 294 rk_aiq_user_api2_alsc_SetAttrib(g_aiq_ctx, lsc_attr); 295 296 //adebayer_attrib_t debayer_attr; 297 //memset(&debayer_attr, 0, sizeof(adebayer_attrib_t)); 298 //rk_aiq_user_api2_adebayer_SetAttrib(g_aiq_ctx, debayer_attr); 299*/ 300 301 while(g_aiq_quit == 0){ 302 if(g_aiq_pause == 0){ 303 CLEAR(buf); 304 305 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 306 buf.memory = V4L2_MEMORY_MMAP; 307 308 struct v4l2_plane planes[FMT_NUM_PLANES]; 309 memset(planes, 0, sizeof(struct v4l2_plane)*FMT_NUM_PLANES); 310 buf.m.planes = planes; 311 buf.length = FMT_NUM_PLANES; 312 313 if (-1 == xioctl(g_ispfd, VIDIOC_DQBUF, &buf)) 314 errno_exit( "VIDIOC_DQBUF"); 315 316 printf("********* DQBUF sucess! buf.sequence %d\n", buf.sequence); 317 i = buf.index; 318 bytesused = buf.m.planes[0].bytesused; 319 320 if(bytesused > 0){ 321 write_yuv_to_file(g_buffers[i].start, bytesused, cnt); 322 } 323 324 if (-1 == xioctl(g_ispfd, VIDIOC_QBUF, &buf)) 325 errno_exit("VIDIOC_QBUF"); 326 usleep(1000); 327 cnt++; 328 } 329 usleep(10000); 330 } 331 332 return 0; 333} 334