//이번 문서는 개인저장용이므로 다소 보기 어려울수도있으니 양해바랍니다.
void CameraInstance::initResolution(int width, int height, int fps)
{
v4l2_format fmt;
CLEAR(fmt); //memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; // V4L2_PIX_FMT_MJPEG; // V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; // V4L2_FIELD_INTERLACED;
this->xioctl(d->mDeviceHandle, VIDIOC_S_FMT, &fmt);
bool CameraInstance::initMMAP(int handle, void*& mmapBuffer)
{
v4l2_requestbuffers req;
CLEAR(req);
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == this->xioctl(handle, VIDIOC_REQBUFS, &req))
{
CLogWriter::printLog(QString("[CameraInstance::] : Requesting Buffer"), CLogWriter::LOG_TYPE_RELEASE);
return false;
}
v4l2_buffer buf ;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if(-1 == this->xioctl(handle, VIDIOC_QUERYBUF, &buf))
{
CLogWriter::printLog(QString("[CameraInstance::] : Quering Buffer"), CLogWriter::LOG_TYPE_RELEASE);
return false;
}
mmapBuffer = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, handle, buf.m.offset);
// printf("Length: %d\nAddress: %p\n", buf.length, buffer);
// printf("Image Length: %d\n", buf.bytesused);
return true;
}
cv::Mat CameraInstance::captureQueryImage(int handle, void* mmapBuffer, int width, int height)
{
v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if(-1 == this->xioctl(handle, VIDIOC_QBUF, &buf))
{
CLogWriter::printLog(QString("[CameraInstance::] : CaptureQuery Buffer"), CLogWriter::LOG_TYPE_RELEASE);
return cv::Mat();
}
if(-1 == this->xioctl(handle, VIDIOC_STREAMON, &buf.type))
{
CLogWriter::printLog(QString("[CameraInstance::] : Capture Error"), CLogWriter::LOG_TYPE_RELEASE);
return cv::Mat();
}
fd_set fds;
FD_ZERO(&fds);
FD_SET(handle, &fds);
timeval tv;
CLEAR(tv);
tv.tv_sec = 2;
int r = select(handle+1, &fds, NULL, NULL, &tv);
if(-1 == r)
{
CLogWriter::printLog(QString("[CameraInstance::] : Waiting for Frame"), CLogWriter::LOG_TYPE_RELEASE);
return cv::Mat();
}
if(-1 == this->xioctl(handle, VIDIOC_DQBUF, &buf))
{
CLogWriter::printLog(QString("[CameraInstance::] : Retrieving Frame"), CLogWriter::LOG_TYPE_RELEASE);
return cv::Mat();
}
cv::Mat matrix(height, width, CV_8UC3, (uchar*)mmapBuffer);
cv::Mat decodedMatrix = cv::imdecode(matrix, CV_LOAD_IMAGE_UNCHANGED );
return decodedMatrix;
}
int CameraInstance::open_device(const char* dev_name, int& fd)
{
struct stat st;
if(-1 == stat(dev_name, &st))
{
CLogWriter::printLog(QString("[CameraInstance::] : %1 : %2, %3").arg(dev_name)
.arg(QString::number(errno).arg(strerror(errno))), CLogWriter::LOG_TYPE_RELEASE);
return ERROR_LOCAL;
}
if(!S_ISCHR(st.st_mode))
{
CLogWriter::printLog(QString("[CameraInstance::] : %1 is not a valid device").arg(dev_name), CLogWriter::LOG_TYPE_RELEASE);
return ERROR_LOCAL;
}
fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
if(-1 == fd)
{
CLogWriter::printLog(QString("[CameraInstance::] : Cannot open '%1' : %2 %3").arg(dev_name)
.arg(QString::number(errno)).arg(strerror(errno)), CLogWriter::LOG_TYPE_RELEASE);
if(EACCES == errno)
{
CLogWriter::printLog(QString("[CameraInstance::] : Insufficient permissions on '%1' : %2 %3").arg(dev_name)
.arg(QString::number(errno)).arg(strerror(errno)), CLogWriter::LOG_TYPE_RELEASE);
}
return ERROR_LOCAL;
}
return SUCCESS_LOCAL;
}
int CameraInstance::errnoexit(const char *s)
{
CLogWriter::printLog(QString("[CameraInstance::] : [%1] : error %2, %3").arg(s).arg(QString::number(errno)).arg(strerror(errno)), CLogWriter::LOG_TYPE_RELEASE);
return ERROR_LOCAL;
}
int CameraInstance::xioctl(int fd, int request, void *arg)
{
int r;
do r = ioctl (fd, request, arg);
while (-1 == r && EINTR == errno);
return r;
}
int CameraInstance::xioctl(int fd, int request, v4l2_queryctrl *arg)
{
int r;
do {
r = ioctl(fd, request, arg);
} while(-1 == r && EINTR == errno);
return r;
}
int CameraInstance::cioctl(int fd, int request, v4l2_control *arg)
{
int r;
do {
r = ioctl(fd, request, arg);
} while(-1 == r && EINTR == errno);
return r;
}
'C++' 카테고리의 다른 글
Raspberry pi qt5.11 컴파일옵션 (0) | 2018.07.04 |
---|---|
라즈베리 파이 환경설정 (0) | 2018.06.22 |
Qt에서 .ini스타일로 파일쓰기 (0) | 2018.04.27 |
Open MP(병렬처리 연산) 간단 사용법 (0) | 2017.12.13 |
c++11용 형변환 유틸리티클래스 (0) | 2017.11.21 |