查询申请到内核缓冲区的信息失败
来源:互联网 发布:淘宝禁品暗语 编辑:程序博客网 时间:2024/05/04 20:47
小弟在网上下的linux的摄像头拍照程序,可是老出现问题
不管是在QT creater 还是OK6410的板上都会一直打印出VIDIOC_REQBUFS
小弟觉得可能是初始化失败,查询申请到内核缓冲区的信息失败,纠结的非常久还是这样……请大神帮帮忙
内核linux3.0.1 摄像头:罗技C210 uboot:1.1.6
#include "camera.h"
#include "ui_camera.h"#include "video.h"
#include <QFile>
#include <QDir>
#include <QSettings>
#include <QTimer>
#include <QDateTime>
#include <QDebug>
static int cam_fd;
unsigned long file_length;
void *img[4];
int isstreaming=0;
struct v4l2_capability cap;
struct v4l2_format fmt;
struct v4l2_requestbuffers req;
struct v4l2_buffer buffer;
const int W=320,H=240;
QDir dir;
Camera::Camera(QWidget *parent) :
QWidget(parent),
ui(new Ui::Camera)
{
ui->setupUi(this);
ui->captrueBtn->installEventFilter(this);
if(cam_init())
{ ui->statusLabel->setText("Ready");
qDebug("camera init!");
}
else
{ ui->statusLabel->setText("Error");
qDebug("camera init error!");
}
if(start_capture())
{
qDebug("stream on");
ui->statusLabel->setText("Ready");
}
else
{
qDebug("stream on error");
ui->statusLabel->setText("Error");
}
//video_play();
timer=new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(100);
//set image path
QSettings setting("pengsir","imagepath");
path=setting.value("path").toString();//read settings
//default path
if (path.isEmpty())
path="/CameraImages/";
qDebug()<<path;
if(dir.exists(path))
qDebug("Work dir is exsist");
else
{
dir.mkdir(path);
qDebug("Work dir is not exsist,Creat dir!");
}
//set path dialog
pathDlg=new QDialog();
pathui.setupUi(pathDlg);
pathui.pathEdit->setText(path);
}
Camera::~Camera()
{
delete ui;
delete pathDlg;
delete timer;
close_cam();
::close(cam_fd);
}
bool Camera::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->captrueBtn)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMatrix mat;
mat.scale(0.7,0.7);
QPixmap tmp=QPixmap(QString::fromUtf8(":/Camera-icon.png")).transformed(mat);
ui->captrueBtn->setPixmap(tmp);
if(grab_picture())
qDebug("grab a pictrue!");
return true;
}
if(event->type()==QEvent::MouseButtonRelease)
{
ui->captrueBtn->setPixmap(QPixmap(QString::fromUtf8(":/Camera-icon.png")));
sleep(1);
ui->statusLabel->setText("Ready");
//qDebug("button release");
return true;
}
return false;
}
return false;
}
void Camera::paintEvent(QPaintEvent *)
{
video_play();
}
bool Camera::cam_init()
{
QFile f(CAM_DEV);
//open device
if(f.exists())
{
cam_fd=::open(CAM_DEV,O_RDWR);
if(cam_fd<0)
{
qDebug("open camera error");
return false;
}
}
//query capability
CLEAR(cap);
if(ioctl (cam_fd, VIDIOC_QUERYCAP, &cap)<0)
{
qDebug("VIDIOC_QUERYCAP:");
return false;
}
qDebug("capabilities:0x%x",cap.capabilities);
//set fomat
CLEAR(fmt);
fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width=W;
fmt.fmt.pix.height=H;
if(ioctl(cam_fd,VIDIOC_S_FMT,&fmt)<0)
{
qDebug("VIDIOC_S_FMT");
return false;
}
fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(cam_fd,VIDIOC_G_FMT,&fmt);
if(fmt.fmt.pix.pixelformat&V4L2_PIX_FMT_JPEG)
qDebug("set format V4L2_PIX_FMT_JPEG");
//file length
file_length=fmt.fmt.pix.bytesperline*fmt.fmt.pix.height;
//request memory
CLEAR(req);
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
req.count=4;
if(ioctl(cam_fd,VIDIOC_REQBUFS,&req)<0)
{
qDebug("VIDIOC_REQBUFS:");
return false;
}
qDebug("request memory!");
//query buffer
int i;
for(i=0;i<4;i++)
{
CLEAR(buffer);
buffer.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buffer.memory=V4L2_MEMORY_MMAP;
buffer.index=i;
if(ioctl(cam_fd,VIDIOC_QUERYBUF,&buffer)<0)
{
qDebug("VIDIOC_QUERYBUF:");
return false;
}
//memory map
img[i]=mmap(0,buffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,cam_fd,buffer.m.offset);
if(img==MAP_FAILED)
{
qDebug("mmap failed:");
return false;
}
}
qDebug("memory mapped!");
//queue the buffer
for(i=0;i<2;i++)
{
CLEAR(buffer);
buffer.index=i;
buffer.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buffer.memory=V4L2_MEMORY_MMAP;
if(ioctl(cam_fd,VIDIOC_QBUF,&buffer)<0)
{
qDebug("VIDIOC_QBUF:");
return false;
}
}
qDebug("queen buffer!");
return true;
}
bool Camera::start_capture()
{
if(!isstreaming)
{
//stream on
if(ioctl(cam_fd,VIDIOC_STREAMON,&buffer.type)<0)
{
qDebug("VIDIOC_STREAMON:");
return false;
}
isstreaming=1;
//qDebug("stream on");
}
return true;
}
void Camera::video_play()
{
//queue out;
if(ioctl (cam_fd, VIDIOC_DQBUF, &buffer)<0)
{
qDebug("VIDIOC_DQBUF:");
//return false;
}
pixmap.loadFromData((uchar*)img[buffer.index],buffer.bytesused,"JPEG");
ui->videoLabel->setPixmap(pixmap);
//queue buffer
ioctl(cam_fd, VIDIOC_QBUF, &buffer);
//return true;
}
bool Camera::grab_picture()
{
QDateTime datetime=QDateTime::currentDateTime();
filename=path+datetime.toString("yyMMddhhmmss");
filename+=".jpg";
qDebug()<<filename;
//pixmap.save(filename,"JPEG",70);
FILE * fd;
//convert QString to char*
char *fn;
QByteArray ba = filename.toLatin1();
fn=ba.data();
fd=fopen(fn,"w+");
fwrite(img[buffer.index],file_length,1,fd);
fclose(fd);
ui->statusLabel->setText("Saved");
return true;
}
bool Camera::close_cam()
{
if(isstreaming)
{
if(ioctl(cam_fd, VIDIOC_STREAMOFF, &buffer.type)<0)
{
qDebug("VIDIOC_STREAMOFF:");
return false;
}
qDebug("stop capture!");
//memory unmap
int i;
for(i=0;i<4;i++)
{
if(munmap(img[i],buffer.length)<0)
{
qDebug("munmap:");
return false;
}
}
qDebug("memory unmapped");
isstreaming=0;
}
return true;
}
void Camera::on_setBtn_clicked()
{
pathDlg->setModal(true);
pathDlg->show();
connect(pathui.okBtn,SIGNAL(clicked()),this,SLOT(okBtn_clicked()));
}
void Camera::okBtn_clicked()
{
pathDlg->hide();
newpath=pathui.pathEdit->text();
if(newpath.isEmpty())//default path is /
newpath="/CameraImages/";
//write settings
QSettings setting("pengsir","imagepath");
setting.setValue("path",newpath);
//pathui.pathEdit->setText(newpath);
if(newpath!=path)
{
path=newpath;
dir.mkdir(newpath);
qDebug()<<"new path:"<<newpath;
//qDebug("New work dir is created!");
}
}
- 查询申请到内核缓冲区的信息失败
- 内核缓冲区的管理
- 内核缓冲区slab的管理
- 查询内核符号链接的信息的API
- 内核缓冲区
- 详细讲解从用户空间申请内存到内核如何为其分配内存的过程
- 修改Linux内核的printk缓冲区(log缓冲区)大小
- 修改Linux内核的printk缓冲区(log缓冲区)大小
- 修改Linux内核的printk缓冲区(log缓冲区)大小
- 内核信息打印到文件
- 观察内核所捕获到的网卡信息
- 我使用过的Linux命令之dmesg - 查看开机信息/打印或控制内核环形缓冲区
- 对申请GSoC2010失败的反思
- 【存储管理】内核缓冲区的管理概述
- 【存储管理】内核缓冲区的管理
- SQL将查询到的信息转为字符串输出
- 系统缓冲区、内核缓冲区、IO库操作本身的缓冲区 之间联系
- 系统缓冲区、内核缓冲区、IO库操作本身的缓冲区 之间联系
- 用gcc编译成可执行程序
- 字符串流的用法
- jboss eap6.1(2)(JBAS015960错误过滤)
- 谈C#中的Delegate
- leetcode: Palindrome Number
- 查询申请到内核缓冲区的信息失败
- ASIFormDataRequest /AFNetworking GET/POST请求的简单封装(block)
- Sandisc 16Gu盘被当做本地硬盘了
- dom4j
- yum常用命令
- tomcat 项目迁移到weblogic
- 慢慢的走出一条属于自己的路
- MSCS quorum.log文件错误解决
- pickle模块, python