V4L2 Camera 驱动 Capture测试程序(三)

2014-11-24 08:47:24 ? 作者: ? 浏览: 5
xit (EXIT_FAILURE);
}

if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
fprintf (stderr, "%s does not support streaming i/o/n",dev_name);
exit (EXIT_FAILURE);
}



CLEAR (cropcap);

cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect;

if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
switch (errno) {
case EINVAL:
break;
default:
break;
}
}
}else { }

CLEAR (fmt);

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
errno_exit ("VIDIOC_S_FMT");

init_mmap ();

}

static void close_device (void)
{
if (-1 == close (fd))
errno_exit ("close");
fd = -1;
close(fbfd);
}

static void open_device (void)
{
struct stat st;

if (-1 == stat (dev_name, &st)) {
fprintf (stderr, "Cannot identify '%s': %d, %s/n",dev_name, errno, strerror (errno));
exit (EXIT_FAILURE);
}

if (!S_ISCHR (st.st_mode)) {
fprintf (stderr, "%s is no device/n", dev_name);
exit (EXIT_FAILURE);
}

//open framebuffer
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd==-1) {
printf("Error: cannot open framebuffer device./n");
exit (EXIT_FAILURE);
}

//open camera
fd = open (dev_name, O_RDWR| O_NONBLOCK, 0);

if (-1 == fd) {
fprintf (stderr, "Cannot open '%s': %d, %s/n",dev_name, errno, strerror (errno));
exit (EXIT_FAILURE);
}
}

static void usage (FILE * fp,int argc,char ** argv)
{
fprintf (fp,
"Usage: %s [options]/n/n"
"Options:/n"
"-d | --device name Video device name [/dev/video]/n"
"-h | --help Print this message/n"
"-t | --how long will display in seconds/n"
"",
argv[0]);
}

static const char short_options [] = "d:ht:";
static const struct option long_options [] = {
{ "device", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "time", no_argument, NULL, 't' },
{ 0, 0, 0, 0 }
};

int main (int argc,char ** argv)
{
dev_name = "/dev/video0";

for (;;)
{
int index;
int c;

c = getopt_long (argc, argv,short_options, long_options,&index);
if (-1 == c)
break;

switch (c) {
case 0:
break;

case 'd':
dev_name = optarg;
break;

case 'h':
usage (stdout, argc, argv);
exit (EXIT_SUCCESS);
case 't':
time_in_sec_capture = atoi(optarg);
break;

default:
usage (stderr, argc, argv);
exit (EXIT_FAILURE);
}
}

open_device ();

init_device ();

start_capturing ();

run ();

stop_capturing ();

uninit_device ();

close_device ();

exit (EXIT_SUCCESS);

return 0;
}


这个测试程序是根据vivi驱动hard code的, 并不一定适合其他的camera驱动
比如,我手头上的logitech stv06xx usb camera, 因为不支持640x480模式,参见代码59 60行,
代码348行 if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) 应该是个协商的过程,
343 fmt.fmt.pix.width = 640;
344 fmt.fmt.pix.height = 480;
345 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
346 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
这几行只是应用的期望格式,驱动会根据这个格式选择一个相近的格式返回,应用最后的显示处理要根据返回的格式进行处理,即process_image要做相应修改


-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: