#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
/*#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
#define VIDIO_G_FMT _IOWR('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
#define VIDIOC_G_FBUF _IOW('V', 10, struct v4l2_buffersfer)
#define VIDIOC_S_BUF _IOW('V', 11, struct v4l2_buffersfer)
#define VIDIOC_OVERLAY _IOW('V', 14, int)
#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
#define VIDIOC_DQBUF _IOWR('V', 17, strut v4l2_buffer)
#define VIDIOC_STREAMON _IOW('V', 18, int)
#define VIDIOC_STREAMOFF _IOW('V', 19, int)
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
*/
#define COUNT 1
#define CAPTURE_FILE "frame.jpg"
struct v4l2_capability cap;
struct v4l2_requestbuffers req;
typedef struct VideoBuffer { char * start; size_t length; } VideoBuffer;
int main(void){
char *dev_name="/dev/video0";
int fd=0;
int ret=0;
//fd=open(dev_name, O_RDWR|O_NONBLOCK, 0);
fd=open(dev_name, O_RDWR, 0);
ret=ioctl(fd,_IOR('V', 0, struct v4l2_capability) ,&cap);
if (ret < 0) {
perror("VIDIOC_QUERYCAP failed ");
return ret;
}
printf("%d\n",fd);
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");
if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
printf("Overlay capability is supported\n");
struct v4l2_format fmt;
memset(&fmt,0,sizeof(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_JPEG;//for PAL
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
if (ret < 0) {
perror("VIDIOC_S_FMT");
return ret;
}
//struct v4l2_buffer * buffers=0;
int n_buffers=0;
memset(&req, 0, sizeof (req));
req.count = COUNT;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ret=ioctl(fd,VIDIOC_REQBUFS,&req);
if (ret == -1)
{
perror("VIDIOC_REQBUFS error n");
//return -1;
}
if (req.count < 2)
printf("insufficient buffer memory\n");
printf("Number of buffers allocated = %d\n", req.count);
/*******step 2*****Getting Physical Address *******/
VideoBuffer * buffers =calloc(req.count, sizeof(*buffers));
struct v4l2_buffer buf;//......
for ( n_buffers = 0; n_buffers < req.count; ++n_buffers)
{
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
if (ret < 0) {
perror("VIDIOC_QUERYBUF");
return ret;
}
/*******step 3*****Mapping Kernel Space Address to User Space*******/
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start= (char*)
mmap(NULL,
buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
perror("mmap failed n");
ret = ioctl(fd , VIDIOC_QBUF, &buf);
if (ret < 0) {
printf("VIDIOC_QBUF (%d) failed (%d)\n", n_buffers, ret);
return -1;
}
printf("Frame buffer %d: address=0x%x, length=%d\n", n_buffers, (unsigned int)buffers[n_buffers].start, buffers[n_buffers].length);
}
/************requestbuffers in queue***********/
/*
int i=0;
//struct v4l2_buffer buf;
//for (i = 0; i < n_buffers; ++i) {
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ret = ioctl(fd, VIDIOC_QBUF, &buf);//.........
if (ret < 0) {
perror("VIDIOC_QBUF");
return ret;
}
}
*/
/************start stream on***********/
enum v4l2_buf_type types;//........
types = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd, VIDIOC_STREAMON, &types);
if (ret < 0) {
perror("VIDIOC_STREAMON");
return ret;
}
// Get frame
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
if (ret < 0) {
printf("VIDIOC_DQBUF failed (%d)\n", ret);
return ret;
}
// Process the frame
FILE *fp = fopen(CAPTURE_FILE, "wb");
if (fp < 0) {
printf("open frame data file failed\n");
return -1;
}
fwrite(buffers[buf.index].start, 1, buf.length, fp);
printf("buff.index=%d\n",buf.index);
fclose(fp);
printf("Capture one frame saved in %s\n", CAPTURE_FILE);
// Re-queen buffer
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if (ret < 0) {
printf("VIDIOC_QBUF failed (%d)\n", ret);
return ret;
}
// Release the resource
int i=0;
for ( i=0; i< COUNT; i++)
{
munmap(buffers[i].start, buffers[i].length);
}
close(fd);
printf("Camera test Done.\n");
return 0;
}
#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
/*#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
#define VIDIO_G_FMT _IOWR('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
#define VIDIOC_G_FBUF _IOW('V', 10, struct v4l2_buffersfer)
#define VIDIOC_S_BUF _IOW('V', 11, struct v4l2_buffersfer)
#define VIDIOC_OVERLAY _IOW('V', 14, int)
#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
#define VIDIOC_DQBUF _IOWR('V', 17, strut v4l2_buffer)
#define VIDIOC_STREAMON _IOW('V', 18, int)
#define VIDIOC_STREAMOFF _IOW('V', 19, int)
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
*/
#define COUNT 1
#define CAPTURE_FILE "frame.jpg"
struct v4l2_capability cap;
struct v4l2_requestbuffers req;
typedef struct VideoBuffer { char * start; size_t length; } VideoBuffer;
int main(void){
char *dev_name="/dev/video0";
int fd=0;
int ret=0;
//fd=open(dev_name, O_RDWR|O_NONBLOCK, 0);
fd=open(dev_name, O_RDWR, 0);
ret=ioctl(fd,_IOR('V', 0, struct v4l2_capability) ,&cap);
if (ret < 0) {
perror("VIDIOC_QUERYCAP failed ");
return ret;
}
printf("%d\n",fd);
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");
if (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
printf("Overlay capability is supported\n");
struct v4l2_format fmt;
memset(&fmt,0,sizeof(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_JPEG;//for PAL
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
if (ret < 0) {
perror("VIDIOC_S_FMT");
return ret;
}
//struct v4l2_buffer * buffers=0;
int n_buffers=0;
memset(&req, 0, sizeof (req));
req.count = COUNT;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ret=ioctl(fd,VIDIOC_REQBUFS,&req);
if (ret == -1)
{
perror("VIDIOC_REQBUFS error n");
//return -1;
}
if (req.count < 2)
printf("insufficient buffer memory\n");
printf("Number of buffers allocated = %d\n", req.count);
/*******step 2*****Getting Physical Address *******/
VideoBuffer * buffers =calloc(req.count, sizeof(*buffers));
struct v4l2_buffer buf;//......
for ( n_buffers = 0; n_buffers < req.count; ++n_buffers)
{
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
if (ret < 0) {
perror("VIDIOC_QUERYBUF");
return ret;
}
/*******step 3*****Mapping Kernel Space Address to User Space*******/
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start= (char*)
mmap(NULL,
buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start)
perror("mmap failed n");
ret = ioctl(fd , VIDIOC_QBUF, &buf);
if (ret < 0) {
printf("VIDIOC_QBUF (%d) failed (%d)\n", n_buffers, ret);
return -1;
}
printf("Frame buffer %d: address=0x%x, length=%d\n", n_buffers, (unsigned int)buffers[n_buffers].start, buffers[n_buffers].length);
}
/************requestbuffers in queue***********/
/*
int i=0;
//struct v4l2_buffer buf;
//for (i = 0; i < n_buffers; ++i) {
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ret = ioctl(fd, VIDIOC_QBUF, &buf);//.........
if (ret < 0) {
perror("VIDIOC_QBUF");
return ret;
}
}
*/
/************start stream on***********/
enum v4l2_buf_type types;//........
types = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd, VIDIOC_STREAMON, &types);
if (ret < 0) {
perror("VIDIOC_STREAMON");
return ret;
}
// Get frame
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
if (ret < 0) {
printf("VIDIOC_DQBUF failed (%d)\n", ret);
return ret;
}
// Process the frame
FILE *fp = fopen(CAPTURE_FILE, "wb");
if (fp < 0) {
printf("open frame data file failed\n");
return -1;
}
fwrite(buffers[buf.index].start, 1, buf.length, fp);
printf("buff.index=%d\n",buf.index);
fclose(fp);
printf("Capture one frame saved in %s\n", CAPTURE_FILE);
// Re-queen buffer
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if (ret < 0) {
printf("VIDIOC_QBUF failed (%d)\n", ret);
return ret;
}
// Release the resource
int i=0;
for ( i=0; i< COUNT; i++)
{
munmap(buffers[i].start, buffers[i].length);
}
close(fd);
printf("Camera test Done.\n");
return 0;
}