requesting and memory-mapping a buffer
git-svn-id: svn://anubis/misc/WebcamTracker@121 bd8a9e45-a331-0410-811e-c64571078777
This commit is contained in:
parent
ca070c2d8c
commit
96eb602808
@ -5,6 +5,9 @@
|
||||
#include <stdlib.h> /* exit() */
|
||||
#include <sys/ioctl.h> /* ioctl() */
|
||||
#include <libv4lconvert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h> /* mmap() */
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include "WebcamTracker.h"
|
||||
using namespace std;
|
||||
@ -23,26 +26,61 @@ WebcamTracker::WebcamTracker(const char * device)
|
||||
m_open = true;
|
||||
|
||||
struct v4l2_capability cap;
|
||||
ioctl(m_fd, VIDIOC_QUERYCAP, &cap);
|
||||
#define check_cap(x) do { \
|
||||
if (cap.capabilities & (x)) \
|
||||
cout << " cap: " << #x << endl; \
|
||||
} while (0)
|
||||
check_cap(V4L2_CAP_VIDEO_CAPTURE);
|
||||
check_cap(V4L2_CAP_VIDEO_OUTPUT);
|
||||
check_cap(V4L2_CAP_VIDEO_OVERLAY);
|
||||
check_cap(V4L2_CAP_VBI_CAPTURE);
|
||||
check_cap(V4L2_CAP_VBI_OUTPUT);
|
||||
check_cap(V4L2_CAP_SLICED_VBI_CAPTURE);
|
||||
check_cap(V4L2_CAP_SLICED_VBI_OUTPUT);
|
||||
check_cap(V4L2_CAP_RDS_CAPTURE);
|
||||
check_cap(V4L2_CAP_VIDEO_OUTPUT_OVERLAY);
|
||||
check_cap(V4L2_CAP_TUNER);
|
||||
check_cap(V4L2_CAP_AUDIO);
|
||||
check_cap(V4L2_CAP_RADIO);
|
||||
check_cap(V4L2_CAP_READWRITE);
|
||||
check_cap(V4L2_CAP_ASYNCIO);
|
||||
check_cap(V4L2_CAP_STREAMING);
|
||||
int ret = ioctl(m_fd, VIDIOC_QUERYCAP, &cap);
|
||||
if (ret != 0)
|
||||
{
|
||||
cerr << "VIDIOC_QUERYCAP ioctl failed: " << ret << endl;
|
||||
}
|
||||
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
|
||||
{
|
||||
cerr << "Warning: V4L2_CAP_VIDEO_CAPTURE not supported!" << endl;
|
||||
}
|
||||
|
||||
v4l2_requestbuffers reqbuf;
|
||||
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
reqbuf.count = 1;
|
||||
reqbuf.memory = V4L2_MEMORY_MMAP;
|
||||
ret = ioctl(m_fd, VIDIOC_REQBUFS, &reqbuf);
|
||||
if (ret != 0)
|
||||
{
|
||||
cerr << "VIDIOC_REQBUFS ioctl failed: returned " << ret
|
||||
<< ", errno " << errno;
|
||||
if (errno == EBUSY)
|
||||
cerr << " (EBUSY)";
|
||||
if (errno == EINVAL)
|
||||
cerr << " (EINVAL)";
|
||||
cerr << endl;
|
||||
}
|
||||
|
||||
struct v4l2_buffer buf;
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.index = 0;
|
||||
ret = ioctl(m_fd, VIDIOC_QUERYBUF, &buf);
|
||||
if (ret != 0)
|
||||
{
|
||||
cerr << "VIDIOC_QUERYBUF ioctl failed: returned " << ret
|
||||
<< ", errno: " << errno;
|
||||
if (errno == EINVAL)
|
||||
cerr << " (EINVAL)";
|
||||
cerr << endl;
|
||||
}
|
||||
|
||||
m_vidbuflen = buf.length;
|
||||
m_vidbuf = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
m_fd, buf.m.offset);
|
||||
if (m_vidbuf == MAP_FAILED)
|
||||
{
|
||||
cerr << "mmap() failed: errno " << errno;
|
||||
if (errno == EBADF)
|
||||
cerr << " (EBADF)";
|
||||
if (errno == EACCES)
|
||||
cerr << " (EACCES)";
|
||||
if (errno == EINVAL)
|
||||
cerr << " (EINVAL)";
|
||||
if (errno == ENOMEM)
|
||||
cerr << " (ENOMEM)";
|
||||
cerr << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -54,6 +92,22 @@ WebcamTracker::~WebcamTracker()
|
||||
{
|
||||
if (m_open)
|
||||
{
|
||||
munmap(m_vidbuf, m_vidbuflen);
|
||||
|
||||
v4l2_requestbuffers reqbuf;
|
||||
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
reqbuf.count = 0;
|
||||
reqbuf.memory = V4L2_MEMORY_MMAP;
|
||||
int ret = ioctl(m_fd, VIDIOC_REQBUFS, &reqbuf);
|
||||
if (ret != 0)
|
||||
{
|
||||
cerr << "~WebcamTracker(): VIDIOC_REQBUFS ioctl failed: "
|
||||
<< ret << endl;
|
||||
if (errno == EBUSY)
|
||||
cerr << "EBUSY" << endl;
|
||||
if (errno == EINVAL)
|
||||
cerr << "EINVAL" << endl;
|
||||
}
|
||||
close(m_fd);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ class WebcamTracker
|
||||
~WebcamTracker();
|
||||
|
||||
protected:
|
||||
void * m_vidbuf;
|
||||
int m_vidbuflen;
|
||||
bool m_open;
|
||||
int m_fd;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user