S3C2440通过v4l2采集在lcd上显示
#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);
}
}