S3C2440通过v4l2采集在lcd上显示与多帧编程
2012-12-27 10:40
120 查看
#include <sys/time.h> #include <sys/types.h> #include <asm/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <errno.h> //#include <jpeglib.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/videodev.h> #include <linux/fb.h> #define COLS 320 #define ROWS 240 #define V4L2_DEV_NODE "/dev/video13" #define FB_DEV_NODE "/dev/fb0" #define CLEAR(x) memset(&(x),0,sizeof(x)) typedef struct v4l2_format V_FORMAT; typedef struct fb_var_screeninfo F_VINFO; struct fb_var_screeninfo fb_var; struct fb_fix_screeninfo fb_fix; char * fb_base_addr = NULL; static void show_rgb565_img(void *scr, __u16 *data_buf) { __u16 x, y; __u16 *fb_buf = (__u16 *)scr; fb_buf += (320); for (y = 0; y < ROWS; y++) { for (x = 0; x < COLS; x++) { fb_buf[x] = *data_buf++ ; } fb_buf += 320; } } int main(void) { int v4l2_fd = -1; int fb_fd = -1; int n=0; __u8 *fb_buf; __u8 *buf; __u32 screensize; //unsigned int width = 0; //unsigned int height = 0; //unsigned int bpp = 0; V_FORMAT fmt; enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Start Main \n"); printf("Before openning video \n"); v4l2_fd = open(V4L2_DEV_NODE, O_RDWR | O_NONBLOCK, 0); if (v4l2_fd < 0) { printf(" open video ERR\n"); return 0; } printf("Before openning FB \n"); fb_fd = open(FB_DEV_NODE, O_RDWR); if (fb_fd < 0) { printf("error open fb_fd\n"); exit(1); } /* Get fixed screen information */ if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_fix)) { printf("Error reading fb fixed information.\n"); exit(1); } /* Get variable screen information */ if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &fb_var)) { printf("Error reading fb variable information.\n"); exit(1); } screensize = fb_var.xres * fb_var.yres * fb_var.bits_per_pixel / 8; //screensize = 480 * 272 * 16 / 8; fb_buf = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); if ((int)fb_buf == -1) { printf("Error: failed to map framebuffer device to memory.\n"); close(fb_fd); return -1; } CLEAR (fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 320; fmt.fmt.pix.height = 240; //fmt.fmt.pix.depth = 16; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565; //printf("VIDIOC_S_FMT is %x\n",VIDIOC_S_FMT); if ((ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt)) < 0) { printf("Error: failed to set video format.\n"); return 0; } buf = malloc(320 * 240 * 3); //printf("VIDIOC_STREAMON is %x\n",VIDIOC_STREAMON); if ((ioctl(v4l2_fd, VIDIOC_STREAMON, &type)) < 0) { printf("error ioctl streamon\n"); return 0; } printf("start to get pic %d\n",(int)fmt.fmt.pix.sizeimage); while(1) { n=read(v4l2_fd, buf, 320*240*2); printf("display %d\n",n); show_rgb565_img(fb_buf,buf); } }
多帧编程
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <getopt.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <malloc.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <asm/types.h> #include <linux/videodev2.h> #define CLEAR(x) memset (&(x), 0, sizeof (x)) struct buffer { void * start; size_t length; }; static char * dev_name = "/dev/video12"; static int fd = -1; struct buffer * buffers = NULL; FILE *file_fd; static unsigned long file_length; //static unsigned char *file_name; int main (int argc,char ** argv) { struct v4l2_capability cap; struct v4l2_format fmt; char fourcc[5] = {0, 0, 0, 0, 0}; file_fd = fopen("test.yuv", "wb"); fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); int ff = ioctl (fd, VIDIOC_QUERYCAP, &cap); if(ff < 0) printf("failture VIDIOC_QUERYCAP\n"); printf("\n****Capability informations****\n"); printf("driver: %s\n", cap.driver); if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) printf("Capture capability is supported\n"); if (cap.capabilities & V4L2_CAP_STREAMING) printf("Streaming capability is supported\n"); CLEAR (fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 720; fmt.fmt.pix.height = 288; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; //视频数据存储类型//V4L2_PIX_FMT_JPEG;//V4L2_PIX_FMT_YVU420;//V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; ff = ioctl (fd, VIDIOC_S_FMT, &fmt); //设置图像格式 if (ff < 0) printf("failture VIDIOC_S_FMT\n"); memmove(fourcc, &fmt.fmt.pix.pixelformat, 4); printf("Goint to capture frames %d x %d format: %4s framesize: %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fourcc, fmt.fmt.pix.sizeimage); file_length = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; //计算图片大小 buffers = calloc (1, sizeof (*buffers)); if (!buffers) { perror("Can't allocate buffer!\n"); return 1; } buffers[0].length = file_length; buffers[0].start = malloc (file_length); for (;;) //这一段涉及到异步IO { fd_set fds; struct timeval tv; //timeval结构的指针,用于决定select等待I/o的最长时间。如果为空将一直等待 int r; FD_ZERO (&fds); //将指定的文件描述符集清空 FD_SET (fd, &fds); //在文件描述符集合中增加一个新的文件描述符 /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; /*readset writeset exceptset指定我们要让内核测试读、写和异常条件的描述字。 如果对某一个的条件不感兴趣,就可以把它设为NULL。 如果三个指针都为NULL,我们就有了一个比sleep()函数更为精确的定时器 (sleep()以秒为最小单位,这个以微妙为单位)。 int select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval * timeout); */ r = select (fd + 1, &fds, NULL, NULL, &tv); //判断是否可读(即摄像头是否准备好),tv是定时 if (-1 == r) { if (EINTR == errno) continue; printf ("select"); } /* if (0 == r) { fprintf (stderr, "select timeout\n"); exit (EXIT_FAILURE); } */ if (read (fd, buffers[0].start, buffers[0].length))//如果可读,执行read()函数,并跳出循环 break; } fwrite(buffers[0].start, buffers[0].length, 1, file_fd); free (buffers[0].start); close (fd); fclose (file_fd); exit (EXIT_SUCCESS); return 0; }
不管是ov511还是zc301的摄像头,它们采集的方式都是相同的,只不过采集到的数据有所差异,ov511的就是rgb的位流,而zc301是jpeg编码的位流。mouse_capture是根据servfox改编的一个专门从zc301摄像头获取一张jpeg图片,用来测试摄像头是否加载成功的小程序。这样就可以不用cat /dev/video0>1.jpg来测试摄像头是否正常。cat命令一运行,就源源不断地采集jpeg流。但是采到的图片只能显示第一个jpeg头和jpeg尾之间的数据。mouse_capture仅仅获得一张完整的jpeg。
相关文章推荐
- S3C2440通过v4l2采集在lcd上显示
- TQ2440 基于V4L2编程框架的 LCD实时显示(上)
- TQ2440 基于V4L2编程框架的 LCD实时显示(下)
- ubuntu通过V4L2采集jpg并显示jpg
- S3C2440 TFT LCD驱动程序编程要点
- 用v4l2和framebuffer实现usb摄像头视频采集并显示
- V4L2视频采集设备应用程序编程总结(转)
- U-boot中通过ENV设置显示设备(如LCD)参数的方法与格式
- S3C2440的LCD显示
- 基于FPGA的LCD+CMOS视频采集显示使用小结
- S3C2440的LCD编程【转】
- Linux下v4l2采集编程笔记
- 基于Linux视频驱动接口V4L2视频采集编程
- S3C2440 TFT LCD驱动程序编程要点
- V4L2通过摄像头采集图片 (转载)
- s3c2440的LCD字符显示
- 网络采集软件核心技术剖析系列(6)---将任意博主的全部博文下载到SQLite数据库中并通过Webbrower显示(将之前的内容综合到一起)
- ARM9(S3C2440)的LCD显示——程序实例讲解
- 关于S3C2440的LCD只能显示2张图片,不能显示多张图片的问题
- 裸机系列——s3c2440lcd汉字显示