转:http://blog.csdn.net/zjbo_123/archive/2010/01/05/5137459.aspx
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CLEAR(x) memset (&(x), 0, sizeof (x))
typedef enum
{
IO_METHOD_READ,
IO_METHOD_MMAP,
IO_METHOD_USERPTR,
} io_method;
struct buffer
{
void *start;
size_t length;
};
static char *dev_name = NULL;
static io_method io = IO_METHOD_MMAP;
static int pixel_format = V4L2_PIX_FMT_YUV420;
static int fd = -1;
struct buffer *buffers = NULL;
static unsigned int n_buffers = 0;
static unsigned int width = 320;
static unsigned int height = 240;
static unsigned int count = 1;
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 (-1 == r && EINTR == errno);
return r;
}
static void process_image(const void *p, ssize_t size)
{
unsigned char *bbuf=(unsigned char *)p;
int ll;
for ( ll= 1024 ; ll< 60000; ll++) if ((bbuf[ll] == 0xFF) && (bbuf[ll+1] == 0xD9)) break;
FILE *fp2;
fp2=fopen("xx.jpg","w");
fwrite(bbuf, 1, ll+2, fp2);
}
static int read_frame(void)
{
struct v4l2_buffer buf;
unsigned int i;
ssize_t read_bytes;
unsigned int total_read_bytes;
switch (io)
{
case IO_METHOD_READ:
total_read_bytes = 0;
do
{
read_bytes = read(fd, buffers[0].start, buffers[0].length);
if (read_bytes < 0)
{
switch (errno)
{
case EIO:
case EAGAIN:
continue;
default:
errno_exit("read");
}
}
total_read_bytes += read_bytes;
} while (total_read_bytes < buffers[0].length);
process_image(buffers[0].start, buffers[0].length);
break;
case IO_METHOD_MMAP:
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
{
switch (errno)