V4L2 camera 驱动 capture测试程序【转】
转自:http://blog.csdn.net/kickxxx/article/details/6336346
在网上找了一个测试程序, 看了看,是根据capture.c修改的。测试步骤如下 . gcc -o capture_image capture_image.c . ctrl+alt+f1 切换到ubuntu的控制台,切换到控制台模式是因为在图形模式下看不到测试图形,这可能和framebuffer的设置有关 . sudo modprobe vivi . sudo ./capture_image -d /dev/video0 这时可以看到在屏幕左上角有一个640x480大小窗口,内容是彩色条格,彩色条格不停的移动,持续时间5秒 在ubuntu下还可以使用cheese测试 . sudo apt-get install cheese . sudo modprobe vivi . 启动 cheese后,就可以看到滚动的彩色条格 附上测试程序 [c-sharp] view plain copy #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 <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>
#include <linux/fb.h>
#define CLEAR(x) memset (&(x), 0, sizeof (x)) struct buffer {
void * start;
size_t length;
}; static char * dev_name = NULL;
static int fd = -;
struct buffer * buffers = NULL;
static unsigned int n_buffers = ;
static int time_in_sec_capture=;
static int fbfd = -;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *fbp=NULL;
static long screensize=; static void errno_exit (const char * s)
{
fprintf (stderr, "%s error %d, %s/n",s, errno, strerror (errno));
exit (EXIT_FAILURE);
} static int xioctl (int fd,int request,void * arg)
{
int r;
do r = ioctl (fd, request, arg);
while (- == r && EINTR == errno);
return r;
} inline int clip(int value, int min, int max) {
return (value > max ? max : value < min ? min : value);
} static void process_image (const void * p){ //ConvertYUVToRGB32
;
unsigned char* in=(char*)p;
int width=;
int height=;
int istride=;
int x,y,j;
int y0,u,y1,v,r,g,b;
long location=; for ( y = ; y < height + ; ++y) {
for (j = , x=; j < width * ; j += ,x +=) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/) +
(y+vinfo.yoffset) * finfo.line_length; y0 = in[j];
u = in[j + ] - ;
y1 = in[j + ];
v = in[j + ] - ; r = ( * y0 + * v + ) >> ;
g = ( * y0 - * u - * v + ) >> ;
b = ( * y0 + * u + ) >> ; fbp[ location + ] = clip(b, , );
fbp[ location + ] = clip(g, , );
fbp[ location + ] = clip(r, , );
fbp[ location + ] = ; r = ( * y1 + * v + ) >> ;
g = ( * y1 - * u - * v + ) >> ;
b = ( * y1 + * u + ) >> ; fbp[ location + ] = clip(b, , );
fbp[ location + ] = clip(g, , );
fbp[ location + ] = clip(r, , );
fbp[ location + ] = ;
}
in +=istride;
}
} static int read_frame (void)
{
struct v4l2_buffer buf;
unsigned int i; CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP; if (- == xioctl (fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return ;
case EIO: default:
errno_exit ("VIDIOC_DQBUF");
}
} assert (buf.index < n_buffers);
printf("v4l2_pix_format->field(%d)/n", buf.field);
//assert (buf.field ==V4L2_FIELD_NONE);
process_image (buffers[buf.index].start);
if (- == xioctl (fd, VIDIOC_QBUF, &buf))
errno_exit ("VIDIOC_QBUF"); return ;
} static void run (void)
{
unsigned int count;
int frames;
frames = * time_in_sec_capture; while (frames-- > ) {
for (;;) {
fd_set fds;
struct timeval tv;
int r;
FD_ZERO (&fds);
FD_SET (fd, &fds); tv.tv_sec = ;
tv.tv_usec = ; r = select (fd + , &fds, NULL, NULL, &tv); if (- == r) {
if (EINTR == errno)
continue;
errno_exit ("select");
} if ( == r) {
fprintf (stderr, "select timeout/n");
exit (EXIT_FAILURE);
} if (read_frame ())
break; }
}
} static void stop_capturing (void)
{
enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (- == xioctl (fd, VIDIOC_STREAMOFF, &type))
errno_exit ("VIDIOC_STREAMOFF");
} static void start_capturing (void)
{
unsigned int i;
enum v4l2_buf_type type; for (i = ; i < n_buffers; ++i) {
struct v4l2_buffer buf;
CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i; if (- == xioctl (fd, VIDIOC_QBUF, &buf))
errno_exit ("VIDIOC_QBUF");
} type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (- == xioctl (fd, VIDIOC_STREAMON, &type))
errno_exit ("VIDIOC_STREAMON"); } static void uninit_device (void)
{
unsigned int i; for (i = ; i < n_buffers; ++i)
if (- == munmap (buffers[i].start, buffers[i].length))
errno_exit ("munmap"); if (- == munmap(fbp, screensize)) {
printf(" Error: framebuffer device munmap() failed./n");
exit (EXIT_FAILURE) ;
}
free (buffers);
} static void init_mmap (void)
{
struct v4l2_requestbuffers req; //mmap framebuffer
fbp = (char *)mmap(NULL,screensize,PROT_READ | PROT_WRITE,MAP_SHARED ,fbfd, );
if ((int)fbp == -) {
printf("Error: failed to map framebuffer device to memory./n");
exit (EXIT_FAILURE) ;
}
memset(fbp, , screensize);
CLEAR (req); req.count = ;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP; if (- == xioctl (fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf (stderr, "%s does not support memory mapping/n", dev_name);
exit (EXIT_FAILURE);
} else {
errno_exit ("VIDIOC_REQBUFS");
}
} if (req.count < ) { //if (req.count < 2)
fprintf (stderr, "Insufficient buffer memory on %s/n",dev_name);
exit (EXIT_FAILURE);
} buffers = calloc (req.count, sizeof (*buffers)); if (!buffers) {
fprintf (stderr, "Out of memory/n");
exit (EXIT_FAILURE);
} for (n_buffers = ; n_buffers < req.count; ++n_buffers) {
struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers; if (- == xioctl (fd, VIDIOC_QUERYBUF, &buf))
errno_exit ("VIDIOC_QUERYBUF"); buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start)
errno_exit ("mmap");
} } static void init_device (void)
{
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop;
struct v4l2_format fmt;
unsigned int min; // Get fixed screen information
if (-==xioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information./n");
exit (EXIT_FAILURE);
} // Get variable screen information
if (-==xioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information./n");
exit (EXIT_FAILURE);
}
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / ; if (- == xioctl (fd, VIDIOC_QUERYCAP, ∩)) {
if (EINVAL == errno) {
fprintf (stderr, "%s is no V4L2 device/n",dev_name);
exit (EXIT_FAILURE);
} else {
errno_exit ("VIDIOC_QUERYCAP");
}
} if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf (stderr, "%s is no video capture device/n",dev_name);
exit (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 ( == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; if (- == 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 = ;
fmt.fmt.pix.height = ;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (- == xioctl (fd, VIDIOC_S_FMT, &fmt))
errno_exit ("VIDIOC_S_FMT"); init_mmap (); } static void close_device (void)
{
if (- == close (fd))
errno_exit ("close");
fd = -;
close(fbfd);
} static void open_device (void)
{
struct stat st; if (- == 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==-) {
printf("Error: cannot open framebuffer device./n");
exit (EXIT_FAILURE);
} //open camera
fd = open (dev_name, O_RDWR| O_NONBLOCK, ); if (- == 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[]);
} 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' },
{ , , , }
}; 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 (- == c)
break; switch (c) {
case :
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 ;
} 这个测试程序是根据vivi驱动hard code的, 并不一定适合其他的camera驱动
比如,我手头上的logitech stv06xx usb camera, 因为不支持640x480模式,参见代码59 60行,
代码348行 if (- == xioctl (fd, VIDIOC_S_FMT, &fmt)) 应该是个协商的过程,
fmt.fmt.pix.width = ;
fmt.fmt.pix.height = ;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
这几行只是应用的期望格式,驱动会根据这个格式选择一个相近的格式返回,应用最后的显示处理要根据返回的格式进行处理,即process_image要做相应修改
V4L2 camera 驱动 capture测试程序【转】的更多相关文章
- v4l2 Camera详细设置【转】
转自:http://blog.csdn.net/smilefyx/article/details/39555289 转载自:http://blog.sina.com.cn/s/blog_602f877 ...
- camera驱动框架分析(下)
sensor的驱动 v4l2_i2c_new_subdev_board先用client = i2c_new_device(adapter, info);创建info对应的i2c_client对象(代表 ...
- 【转】android camera(四):camera 驱动 GT2005
关键词:android camera CMM 模组 camera参数 GT2005 摄像头常见问题 平台信息: 内核:linux系统:android 平台:S5PV310(samsung exyn ...
- DAVINCI DM6446 开发攻略——V4L2视频驱动和应用分析
针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavista linux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavis ...
- MTK6577+Android之Camera驱动
MTK6577+Android之Camera驱动 <MTK安卓平台的Camera效果在线调试> 1. Camera拍照相关概念 1.1 ISP isp--(Image Signa ...
- camera驱动框架分析(上)【转】
转自:https://www.cnblogs.com/rongpmcu/p/7662738.html 前言 camera驱动框架涉及到的知识点比较多,特别是camera本身的接口就有很多,有些是直接连 ...
- camera驱动框架分析(上)
前言 camera驱动框架涉及到的知识点比较多,特别是camera本身的接口就有很多,有些是直接连接到soc的camif口上的,有些是通过usb接口导出的,如usb camera.我这里主要讨论前者, ...
- (转)FS_S5PC100平台上Linux Camera驱动开发详解(二)
4-3 摄像头的初始化流程及v4l2子设备驱动 这个问题弄清楚了以后下面就来看获得Camera信息以后如何做后续的处理: 在fimc_init_global调用结束之后我们获得了OV9650的信息,之 ...
- Android高通平台调试Camera驱动全纪录
项目比较紧,3周内把一个带有外置ISP,MIPI数据通信,800万像素的camera从无驱动到实现客户全部需求. 1日 搭平台,建环境,编译内核,烧写代码. 我是一直在Window下搭个虚拟机登服务器 ...
随机推荐
- 笔记-git-协作开发
笔记-git-协作开发 1. git协作开发 git协作的典型做法是,创建一个git服务器,被多个人操作. 示意图如下: 一般来说协作分为如下几个步骤: 创建一个git裸服务器 (git i ...
- Hive 表数据的存储和压缩格式
SerDe * 按行存储 * 按列存储 file_format: : | SEQUENCEFILE 序列化(行存储) | TEXTFILE 文本格式(行存储)- (Default, depending ...
- TouTiao开源项目 分析笔记8 图解分析数据加载方式
1.整体构架 1.1.以一个段子页面为例,列出用到的主要的类,以图片的方式展示. 1.2.基础类 这里最基础的接口有: IBaseView<T>==>定义了5个方法. 然后最基础 ...
- Java Spring Controller 获取请求参数的几种方法
技术交流群:233513714 1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交.若"Content-Type"=& ...
- Field 'flag' doesn't have a default value错误
错误代码: java.sql.SQLException: Field 'flag' doesn't have a default value at com.mysql.jdbc.SQLError.cr ...
- 我给女朋友讲编程CSS系列(4) CSS盒子模型
什么是CSS盒子模型?如何学习CSS的盒子模型? 这篇文章,以 [分享 + 结论] 的方式来写. 1, 看w3school的[CSS 框模型概述] 网址为: http://www.w3school ...
- appium-在页面点击一下处理(一般处理提示蒙层)
在写用例的时候,经常会发现某些第一次进去的页面会有一个蒙层提示.我们只有处理掉这个蒙层,才能继续我们的用例: 这边我们使用的是TouchAction的tap方法 TouchAction action ...
- APPIUM-----自动发现兼容的Chromedrivers
使用Appium Desired Capabilities:chromedriverExecutableDir chromeDriver所有版本下载路径:https://chromedriver.st ...
- Java基础-6流程控制
一).选择控制: 选择控制分为两种:if...else...和switch 单分支结构:这是最简单的一种选择结构,它只是简单的判断某个条件是否成立,如果成立就执行一段代码,语句形式为: if(条件表达 ...
- 1.0 python-client以及ui自动化介绍
appium的client-----捕获元素和对元素进行操作都是在client里面去写脚本实现的,client会将你写的python脚本发送到appium server上,然后appium serv ...