查询申请到内核缓冲区的信息失败

来源:互联网 发布:淘宝禁品暗语 编辑:程序博客网 时间: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!");
    }
}

原创粉丝点击