int v4l_capture_setup(void) { struct v4l2_format fmt; struct v4l2_streamparm parm; struct v4l2_fmtdesc fmtdesc; struct v4l2_frmivalenum frmival; struct v4l2_crop crop; struct v4l2_control vc; int fd_v4l = 0; if ((fd_v4l = find_video_device()) < 0) { printf("Unable to open v4l2 capture device.\n"); return 0; } fmtdesc.index = 0; while (ioctl(fd_v4l, VIDIOC_ENUM_FMT, &fmtdesc) >= 0) { print_pixelformat("pixelformat (output by camera)", fmtdesc.pixelformat); frmival.index = 0; frmival.pixel_format = fmtdesc.pixelformat; frmival.width = g_in_width; frmival.height = g_in_height; while (ioctl(fd_v4l, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) { printf("%.3f fps\n", 1.0 * frmival.discrete.denominator / frmival.discrete.numerator); frmival.index++; } fmtdesc.index++; } parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.capturemode = g_capture_mode; parm.parm.capture.timeperframe.denominator = g_camera_framerate; parm.parm.capture.timeperframe.numerator = 1; if (ioctl(fd_v4l, VIDIOC_S_PARM, &parm) < 0) { printf("VIDIOC_S_PARM failed\n"); return -1; } memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.pixelformat = g_cap_fmt; print_pixelformat("pixelformat (output by v4l)", fmt.fmt.pix.pixelformat); fmt.fmt.pix.width = g_in_width; fmt.fmt.pix.height = g_in_height; if (ioctl(fd_v4l, VIDIOC_S_FMT, &fmt) < 0) { printf("set format failed\n"); return 0; } if (ioctl(fd_v4l, VIDIOC_G_FMT, &fmt) < 0) { printf("get format failed\n"); return -1; } else { printf("\t Width = %d", fmt.fmt.pix.width); printf("\t Height = %d", fmt.fmt.pix.height); printf("\t Image size = %d\n", fmt.fmt.pix.sizeimage); } g_frame_size = fmt.fmt.pix.sizeimage; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; fmt.fmt.win.w.left = 0; fmt.fmt.win.w.top = 0; fmt.fmt.win.w.width = g_out_width; fmt.fmt.win.w.height = g_out_height; if (ioctl(fd_v4l, VIDIOC_S_FMT, &fmt) < 0) { printf("set format failed\n"); return 0; } memset(&crop, 0, sizeof(crop)); crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c.top = 0; crop.c.left = 0; crop.c.width = g_in_width; crop.c.height = g_in_height; if (ioctl(fd_v4l, VIDIOC_S_CROP, &crop) < 0) { printf("set crop failed.\n"); return -1; } memset(&crop, 0, sizeof(crop)); crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd_v4l, VIDIOC_G_CROP, &crop) < 0) { printf("get crop failed.\n"); return -1; } else printf("crop.c.l/t/w/h = %d/%d/%d/%d\n", crop.c.left, crop.c.top, crop.c.width, crop.c.height); if (g_hflip) vc.value = 1; else vc.value = 0; vc.id = V4L2_CID_HFLIP; if (ioctl(fd_v4l, VIDIOC_S_CTRL, &vc) < 0) { printf("s_ctrl failed.\n"); return -1; } if (g_vflip) vc.value = 1; else vc.value = 0; vc.id = V4L2_CID_VFLIP; if (ioctl(fd_v4l, VIDIOC_S_CTRL, &vc) < 0) { printf("s_ctrl failed.\n"); return -1; } vc.id = V4L2_CID_PRIVATE_BASE; vc.value = g_rotation; if (ioctl(fd_v4l, VIDIOC_S_CTRL, &vc) < 0) { printf("s_ctrl failed.\n"); return -1; } return fd_v4l; }
void *stream_func(void *ptr) { unsigned char *rgb_buffer; int ready_buf; char cur_name[64]; int i; if( b_shared_mem ) { rgb_buffer = p_shm; } else { rgb_buffer = (unsigned char *)malloc(req_width*req_height*3); } for(i=0; i<total_buffers; i++) { queue_buffer(i); } for(;;) { /* get the idx of ready buffer */ for(i=0; i<total_buffers; i++) { /* Check if the thread should stop. */ if( stream_finish ) return NULL; ready_buf = dequeue_buffer(); if( b_verbose ) { printf("Buffer %d ready. Length: %uB\n", ready_buf, image_buffers[ready_buf].length); } switch( check_pixelformat() ) { case V4L2_PIX_FMT_YUYV: /* convert data to rgb */ if( b_shared_mem ) sem_down(&shm_sem); if( convert_yuv_to_rgb_buffer( (unsigned char *)(image_buffers[ready_buf].start), rgb_buffer, req_width, req_height) == 0 ) { if( b_verbose ) { printf("\tConverted to rgb.\n"); } } if( b_shared_mem ) sem_up(&shm_sem); break; default: print_pixelformat(stderr); fprintf(stderr,"\n"); return NULL; } /* make the image */ /* create the file name */ if( b_named_pipe ) sprintf(cur_name, "%s", psz_named_pipe); switch( e_outfmt ) { case FORMAT_BMP: if( b_shared_mem ) { printf("Unsupported!\n"); break; } make_bmp(rgb_buffer, cur_name, req_width, req_height); break; case FORMAT_RGB: if( b_shared_mem ) { /* The buffer is already rgb :) */ break; } make_rgb(rgb_buffer, cur_name, req_width, req_height); break; default: fprintf(stderr, "Not supported format requested!\n"); break; } queue_buffer(ready_buf); } } return NULL; }
int mxc_v4l_overlay_setup(struct v4l2_format *fmt) { struct v4l2_streamparm parm; v4l2_std_id id; struct v4l2_control ctl; struct v4l2_crop crop; struct v4l2_frmsizeenum fsize; struct v4l2_fmtdesc ffmt; printf("sensor supported frame size:\n"); fsize.index = 0; while (ioctl(fd_v4l, VIDIOC_ENUM_FRAMESIZES, &fsize) >= 0) { printf(" %dx%d\n", fsize.discrete.width, fsize.discrete.height); fsize.index++; } ffmt.index = 0; while (ioctl(fd_v4l, VIDIOC_ENUM_FMT, &ffmt) >= 0) { print_pixelformat("sensor frame format", ffmt.pixelformat); ffmt.index++; } parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.timeperframe.numerator = 1; parm.parm.capture.timeperframe.denominator = g_camera_framerate; parm.parm.capture.capturemode = g_capture_mode; if (ioctl(fd_v4l, VIDIOC_S_PARM, &parm) < 0) { printf("VIDIOC_S_PARM failed\n"); return TFAIL; } parm.parm.capture.timeperframe.numerator = 0; parm.parm.capture.timeperframe.denominator = 0; if (ioctl(fd_v4l, VIDIOC_G_PARM, &parm) < 0) { printf("get frame rate failed\n"); return TFAIL; } printf("frame_rate is %d\n", parm.parm.capture.timeperframe.denominator); ctl.id = V4L2_CID_PRIVATE_BASE + 2; ctl.value = g_rotate; if (ioctl(fd_v4l, VIDIOC_S_CTRL, &ctl) < 0) { printf("set control failed\n"); return TFAIL; } crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; crop.c.left = g_sensor_left; crop.c.top = g_sensor_top; crop.c.width = g_sensor_width; crop.c.height = g_sensor_height; if (ioctl(fd_v4l, VIDIOC_S_CROP, &crop) < 0) { printf("set cropping failed\n"); return TFAIL; } if (ioctl(fd_v4l, VIDIOC_S_FMT, fmt) < 0) { printf("set format failed\n"); return TFAIL; } if (ioctl(fd_v4l, VIDIOC_G_FMT, fmt) < 0) { printf("get format failed\n"); return TFAIL; } if (ioctl(fd_v4l, VIDIOC_G_STD, &id) < 0) { printf("VIDIOC_G_STD failed\n"); return TFAIL; } return TPASS; }
void *capture_func(void *ptr) { unsigned char *rgb_buffer; int ready_buf; char cur_name[64]; int i; struct timeval timestamp; if( b_shared_mem ) { rgb_buffer = p_shm; } else { rgb_buffer = (unsigned char *)malloc(req_width*req_height*3); } for(;;) { /* Wait for the start condition */ pthread_mutex_lock(&cond_mutex); pthread_cond_wait(&condition, &cond_mutex); pthread_mutex_unlock(&cond_mutex); /* queue one buffer and 'refresh it' */ /* @todo Change 2 to some #define */ for(i=0; i<2; i++) { queue_buffer(i); } for(i=0; i<2 - 1; i++) { dequeue_buffer(); } /* get the idx of ready buffer */ ready_buf = dequeue_buffer(); if( b_verbose ) { printf("Buffer %d ready. Length: %uB\n", ready_buf, image_buffers[ready_buf].length); } switch( check_pixelformat() ) { case V4L2_PIX_FMT_YUYV: /* convert data to rgb */ if( convert_yuv_to_rgb_buffer( (unsigned char *)(image_buffers[ready_buf].start), rgb_buffer, req_width, req_height) == 0 ) { if( b_verbose ) { printf("\tConverted to rgb.\n"); } } break; default: print_pixelformat(stderr); fprintf(stderr,"\n"); return NULL; } timestamp = query_buffer(0); /* make the image */ /* create the file name */ if( b_named_filename ) { sprintf(cur_name, "%s%s", psz_output_dir, psz_output_filename); } else if( !b_named_pipe ) sprintf(cur_name, "%scamshot_%lu.bmp", psz_output_dir, timestamp.tv_sec); else sprintf(cur_name, "%s", psz_named_pipe); switch( e_outfmt ) { case FORMAT_BMP: make_bmp(rgb_buffer, cur_name, req_width, req_height); break; case FORMAT_RGB: make_rgb(rgb_buffer, cur_name, req_width, req_height); break; default: fprintf(stderr, "Not supported format requested!\n"); break; } } return NULL; }