视频监控分为两部分,PC端,ARM板端。 PC端的软件界面是用QT写的, 登入名等用到QSql数据库的一些相关知识,也有仿照锐捷客户端来设计界面。
在这里小抱怨下锐捷客户端啦,不过已经有人破解咯。 那首先,我们通过PC段输入用户名,密码,用户名密码都存在数据库里,当然用户名密码都是可以更改的。
之后登入上,选择连接选项,输入开发板IP,连接。传数据是用socket编程。不过在此之前,还要配置好PC机IP,用网线来传送数据,那么在局域网内把IP设为同一网段。这边在ARM板用
ifconfig命令查看子网掩码,IP,网关等。 之后在PC设置。 之前要准备的文件系统,环境配置就不多说,前篇博文“音乐播放器”有讲解。 一切就绪,那就来行使监控功能了。
ARM端用SecureCRT工具来查看。
PC端IP设置。
PC端登入界面(英文界面),不过本人把图片标题给隐藏了,因为上面有学校校徽怕侵权啦。
PC端登入界面(中文界面)。
输入正确用户名密码登入进次界面。
菜单栏上面设置选项下面有个连接选项,选择那么跳出此界面。端口号,这个就是程序里已经给定。比如说http就是80端口,这边我们设定为666.
当然也可以是其他,只要不和其他端口冲突即可。
这边就是摄像头即将要获取的图像,之所以把书目贴出来,是希望对大家有些帮助。
PC端监控画面。
ARM板端监控画面,可以看到和PC端是一样的。 不过PC端会比ARM端稍稍延时。
部分源码:
#include "editpasswd.h" #include "connection.h" EditPasswd::EditPasswd(QWidget *parent) : QDialog(parent) { this->setWindowTitle(tr("passwd modified")); QGridLayout *gridLayout=new QGridLayout; QVBoxLayout *vboxLayout=new QVBoxLayout(this); oldLabel=new QLabel(tr("current passward")); newLabel=new QLabel(tr("new passward")); renewLabel=new QLabel(tr("confirm new passward")); oldLineEdit=new QLineEdit(this); newLineEdit=new QLineEdit(this); renewLineEdit=new QLineEdit(this); okButton=new QPushButton(tr("ok")); oldLabel->setBuddy(oldLineEdit); newLabel->setBuddy(newLineEdit); renewLabel->setBuddy(renewLineEdit); gridLayout->setMargin(15); gridLayout->setSpacing(10); gridLayout->addWidget(oldLabel,0,0); gridLayout->addWidget(oldLineEdit,0,2); gridLayout->addWidget(newLabel,1,0); gridLayout->addWidget(newLineEdit,1,2); gridLayout->addWidget(renewLabel,2,0); gridLayout->addWidget(renewLineEdit,2,2); newLineEdit->setStatusTip(tr("please input passward of six figures")); newLineEdit->setMaxLength(6); oldLineEdit->setEchoMode(QLineEdit::Password); newLineEdit->setEchoMode(QLineEdit::Password); renewLineEdit->setMaxLength(6); renewLineEdit->setEchoMode(QLineEdit::Password); vboxLayout->addLayout(gridLayout); vboxLayout->addWidget(okButton,0,Qt::AlignBottom|Qt::AlignCenter); oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); connect(okButton,SIGNAL(clicked()),this,SLOT(slotok())); } void EditPasswd::slotok() { if(oldLineEdit->text().isEmpty()||newLineEdit->text().isEmpty()||renewLineEdit->text().isEmpty()) { QMessageBox::warning(this, tr("warning"), tr("please complete the inoformation!"), QMessageBox::Ok); } else { if(newLineEdit->text().length()!=6) { QMessageBox::information(this, tr("information"), tr("The new passward is not six figures!"), QMessageBox::Ok); } else if(newLineEdit->text()!=renewLineEdit->text()) { QMessageBox::information(this, tr("information"), tr("The two passwards you typed do not match,please input again!"), QMessageBox::Ok); oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); } else { QSqlQuery query; query.exec("select * from logininfor"); query.next(); if(query.value(1).toString()==oldLineEdit->text()) { bool temp=query.exec(QString("update logininfor set passward='%1' where passward='%2'") .arg(newLineEdit->text()).arg(oldLineEdit->text())); if(temp) { QMessageBox::information(this, tr("information"), tr("passward modification success!"), QMessageBox::Ok); oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); } else { QMessageBox::information(this, tr("information"), tr("passward change failure,can't access database!"), QMessageBox::Ok); oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); } } else { QMessageBox::warning(this, tr("warning"), tr("The current passward is mistake,please input again!"), QMessageBox::Ok); oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); } } } } EditPasswd::~EditPasswd() { oldLineEdit->text().clear(); newLineEdit->text().clear(); renewLineEdit->text().clear(); }
#include "logininterface.h" #include "ui_logininterface.h" #include<QMessageBox> #include<QCheckBox> #include<QDebug> #include<QtSql> LoginInterface::LoginInterface(QWidget *parent) : QDialog(parent), ui(new Ui::LoginInterface) { ui->setupUi(this); ui->lineEdit_passwd->setEchoMode(QLineEdit::Password); ifChinese=0; ui->comboBox->setCurrentIndex(1); connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(change_Language())); } LoginInterface::~LoginInterface() { delete ui; } void LoginInterface::on_pushButtonlogin_clicked() { if(ui->lineEdit_passwd->text().isEmpty()|ui->lineEdit_usr->text().isEmpty()) { QMessageBox::information(this, tr("please input user and passward"), tr("please input user and passward first!"), QMessageBox::Ok); ui->lineEdit_usr->setFocus(); } else { QSqlQuery query; query.exec("select * from logininfor"); query.next(); if ((query.value(0).toString().trimmed() == ui->lineEdit_usr->text()) &&(query.value(1).toString().trimmed() == ui->lineEdit_passwd->text())) { QDialog::accept(); } else { QMessageBox::warning(this, tr("user or passward is wrong"), tr("please input correct user and passward to login!"), QMessageBox::Ok); if(!ui->checkBoxsave->isChecked()) { qDebug()<<"execute"; ui->lineEdit_passwd->clear(); ui->lineEdit_usr->clear(); ui->lineEdit_usr->setFocus();//设置光标的初始位置 } } } } void LoginInterface::on_pushButtonexit_clicked() { switch( QMessageBox::information(this,tr("video monitor system"),tr("Are you sure to exit?"), QMessageBox::Yes,QMessageBox::No)) { case QMessageBox::Yes: this->close(); case QMessageBox::No: return; } } void LoginInterface::change_Language() { if(ui->comboBox->currentIndex()==0) { ifChinese=1; ui->labelusr->setText(tr("用户名")); ui->labelpasswd->setText(tr("密码")); this->setWindowTitle(tr("视频监控系统")); ui->pushButtonexit->setText(tr("退出")); ui->pushButtonlogin->setText(tr("登陆")); ui->checkBoxsave->setText(tr("保存密码")); } else { ifChinese=0; } }
#include "mainwindow.h" #include<QtSql> mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent) { this->setWindowTitle(tr("video monitor system")); label=new QLabel(this); this->setCentralWidget(label); this->resize(700,525); socket=new QTcpSocket(this); datasize=0; createAction(); createMenu(); this->label->setStyleSheet("background-image:url(:/new/Storm.jpg)"); } void mainWindow::createAction() { openAction =new QAction(tr("open"),this); openAction->setShortcut(tr("Ctrl+O")); connect(openAction,SIGNAL(triggered()),this,SLOT(openFile())); exitAction=new QAction(tr("exit"),this); exitAction->setShortcut(tr("Ctrl+E")); connect(exitAction,SIGNAL(triggered()),this,SLOT(exitMessage())); helpAction=new QAction(tr("help"),this); helpAction->setShortcut(tr("Ctrl+H")); connect(helpAction,SIGNAL(triggered()),this,SLOT(helpShow())); passwdAction=new QAction(tr("change passward"),this); passwdAction->setShortcut(tr("Ctrl+P")); connectAction=new QAction(tr("connect"),this) ; connectAction->setShortcut(tr("Ctrl+S")); connect(passwdAction,SIGNAL(triggered()),this,SLOT(passwdShow())); connect(connectAction,SIGNAL(triggered()),this,SLOT(connectMessage())); connect(socket,SIGNAL(readyRead()),this,SLOT(readMessage())); } void mainWindow::createMenu() { fileMenu=this->menuBar()->addMenu(tr("menu")); editMenu=this->menuBar()->addMenu(tr("setup")); aboutMenu=this->menuBar()->addMenu(tr("help")); fileMenu->addAction(openAction); fileMenu->addAction(exitAction); editMenu->addAction(passwdAction); editMenu->addAction(connectAction); aboutMenu->addAction(helpAction); } void mainWindow::openFile() { } void mainWindow::helpShow() { QMessageBox::about( this, tr( "About Video Monitor System" ), tr( "<p><b><b><b>Video Monitor System</b></b></b></p><p></p>" "<p>Version 0.0.0 (2012-10-10)</p><p></p>" "<p>If you have some questions,mail(stu_lizi@sina.cn)</p><p></p>" "<p>For more infomation, please visit our monitor system</p>" "<p><a href = http://www.baidu.com>http://www.baidu.com</a></p>" ) ); } void mainWindow::passwdShow() { qApp->processEvents(); w.setFixedSize(500,150); w.oldLineEdit->setFocus(); w.oldLineEdit->clear(); w.newLineEdit->clear(); w.renewLineEdit->clear(); w.show(); } void mainWindow::exitMessage() { switch(QMessageBox::information(this,tr("video monitor system"),tr("Are you sure to exit?"), QMessageBox::Yes,QMessageBox::No)) { case QMessageBox::Yes: this->close(); break; case QMessageBox::No: break; default: break; } } void mainWindow::connectMessage() { widget=new QWidget; connectui.setupUi(widget); widget->show(); widget->setWindowTitle(tr("server information")); connect(connectui.pushButtonconnect,SIGNAL(clicked()),this,SLOT(connectserver())); } void mainWindow::connectserver() { socket->connectToHost(connectui.lineEditip->text(),connectui.lineEdit_port->text().toInt()); if(!socket->waitForConnected(3000)) { QMessageBox::information(this,tr("server information"),tr("please confirm your iP address、port,the server is running"),QMessageBox::Ok); return; } widget->close(); } void mainWindow::readMessage() { while(socket->bytesAvailable()>0) { if(datasize==0) { QDataStream in(socket); in.setVersion(QDataStream::Qt_4_5); if(socket->bytesAvailable()<sizeof(quint64)) return ; in>>datasize; } qDebug()<<datasize; if(datasize > socket->bytesAvailable()) return ; QByteArray array=socket->read(datasize); QBuffer buffer(&array); buffer.open(QIODevice::ReadOnly); QImageReader reader(&buffer,"bmp"); image=reader.read(); if(!image.isNull()) { datasize=0; socket->reset(); label->setSizeIncrement(image.size()); label->setPixmap(QPixmap::fromImage(image)); } else { qDebug()<<"error!!!!!!!!!!!"; } } }
#include <QtGui/QApplication> #include "logininterface.h" #include"mainwindow.h" #include"connection.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030")); if(!createConnection()) { return 0; } LoginInterface w; QTranslator translator; if(w.exec()==QDialog::Accepted) { if(w.ifChinese==1) { translator.load(":/new/en.qm"); a.installTranslator(&translator); } QPixmap pixmap(":/new/smile.bmp"); QSplashScreen splash(pixmap); splash.show(); splash.resize(700,525); a.processEvents(); mainWindow window; window.show(); splash.finish(&window); return a.exec(); } return 0; }
#include <QtGui> #include "processImage.h" #include "videodevice.h" extern "C" { #include <stdio.h> #include <stdlib.h> } ProcessImage::ProcessImage(QWidget *parent):QWidget(parent) { socket=new QTcpSocket(this); server=new QTcpServer(this); if(!server->listen(QHostAddress::Any,666)) { qDebug()<<"can't listen boys"; return ; } check=0; pp = (unsigned char *)malloc(320 * 240/*QWidget::width()*QWidget::height()*/* 3 * sizeof(char)); painter = new QPainter(this); frame = new QImage(pp,320,240,QImage::Format_RGB888); // frame = new QPixmap(640,320); label = new QLabel(); vd = new VideoDevice(tr("/dev/video0")); connect(vd, SIGNAL(display_error(QString)), this,SLOT(display_error(QString))); rs = vd->open_device(); if(-1==rs) { QMessageBox::warning(this,tr("error"),tr("open /dev/dsp error"),QMessageBox::Yes); vd->close_device(); } rs = vd->init_device(); if(-1==rs) { QMessageBox::warning(this,tr("error"),tr("init failed"),QMessageBox::Yes); vd->close_device(); } rs = vd->start_capturing(); if(-1==rs) { QMessageBox::warning(this,tr("error"),tr("start capture failed"),QMessageBox::Yes); vd->close_device(); } if(-1==rs) { QMessageBox::warning(this,tr("error"),tr("get frame failed"),QMessageBox::Yes); vd->stop_capturing(); } timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(update())); timer->start(30); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->addWidget(label); setLayout(hLayout); setWindowTitle(tr("Capture")); connect(server,SIGNAL(newConnection()),this,SLOT(sendMessage())); } ProcessImage::~ProcessImage() { rs = vd->stop_capturing(); rs = vd->uninit_device(); rs = vd->close_device(); } void ProcessImage::paintEvent(QPaintEvent *) { if(check==1) { rs = vd->get_frame((void **)&p,&len); convert_yuv_to_rgb_buffer(p,pp,320,240/*QWidget::width(),QWidget::height()*/); frame->loadFromData((uchar *)pp,/*len*/320 * 240 * 3 * sizeof(char)); QByteArray data; QBuffer buffer; frame->save(&buffer,"BMP"); QDataStream out(&data,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_5); out<<(quint64)buffer.data().size(); data.append(buffer.data()); socket->write(data); socket->flush(); data.resize(0); // painter->begin(this); // painter->drawImage(0,0,*frame); // painter->end(); // rs = vd->unget_frame(); // frame->load("./img3.jpg"); label->setPixmap(QPixmap::fromImage(*frame,Qt::AutoColor)); // label->show(); rs = vd->unget_frame(); // label->drawFrame(); // QPixmap *pixImage = new QPixmap(); // pixImage->loadFromData((uchar *)pp,sizeof(pp),0,Qt::AutoColor); // QPainter painter(this); // painter.begin(this); // painter.drawPixmap(0,0,QWidget::width(),QWidget::height(),*pixImage); // painter.end(); } } void ProcessImage::display_error(QString err) { QMessageBox::warning(this,tr("error"), err,QMessageBox::Yes); } /*yuv*/ int ProcessImage::convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height) { unsigned int in, out = 0; unsigned int pixel_16; unsigned char pixel_24[3]; unsigned int pixel32; int y0, u, y1, v; for(in = 0; in < width * height * 2; in += 4) { pixel_16 = yuv[in + 3] << 24 | yuv[in + 2] << 16 | yuv[in + 1] << 8 | yuv[in + 0]; y0 = (pixel_16 & 0x000000ff); u = (pixel_16 & 0x0000ff00) >> 8; y1 = (pixel_16 & 0x00ff0000) >> 16; v = (pixel_16 & 0xff000000) >> 24; pixel32 = convert_yuv_to_rgb_pixel(y0, u, v); pixel_24[0] = (pixel32 & 0x000000ff); pixel_24[1] = (pixel32 & 0x0000ff00) >> 8; pixel_24[2] = (pixel32 & 0x00ff0000) >> 16; rgb[out++] = pixel_24[0]; rgb[out++] = pixel_24[1]; rgb[out++] = pixel_24[2]; pixel32 = convert_yuv_to_rgb_pixel(y1, u, v); pixel_24[0] = (pixel32 & 0x000000ff); pixel_24[1] = (pixel32 & 0x0000ff00) >> 8; pixel_24[2] = (pixel32 & 0x00ff0000) >> 16; rgb[out++] = pixel_24[0]; rgb[out++] = pixel_24[1]; rgb[out++] = pixel_24[2]; } return 0; } int ProcessImage::convert_yuv_to_rgb_pixel(int y, int u, int v) { unsigned int pixel32 = 0; unsigned char *pixel = (unsigned char *)&pixel32; int r, g, b; r = y + (1.370705 * (v-128)); g = y - (0.698001 * (v-128)) - (0.337633 * (u-128)); b = y + (1.732446 * (u-128)); if(r > 255) r = 255; if(g > 255) g = 255; if(b > 255) b = 255; if(r < 0) r = 0; if(g < 0) g = 0; if(b < 0) b = 0; pixel[0] = r * 220 / 256; pixel[1] = g * 220 / 256; pixel[2] = b * 220 / 256; return pixel32; }
#include "videodevice.h" VideoDevice::VideoDevice(QString dev_name) { this->dev_name = dev_name; this->fd = -1; this->buffers = NULL; this->n_buffers = 0; this->index = -1; } int VideoDevice::open_device() { fd = open(dev_name.toStdString().c_str(), O_RDWR/*|O_NONBLOCK*/, 0); // fd = open(dev_name.toStdString().c_str(), O_RDWR|O_NONBLOCK, 0); if(-1 == fd) { emit display_error(tr("open: %1").arg(QString(strerror(errno)))); return -1; } return 0; } int VideoDevice::close_device() { if(-1 == close(fd)) { emit display_error(tr("close: %1").arg(QString(strerror(errno)))); return -1; } return 0; } int VideoDevice::init_device() { v4l2_capability cap; v4l2_cropcap cropcap; v4l2_crop crop; v4l2_format fmt; if(-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap)) { if(EINVAL == errno) { emit display_error(tr("%1 is no V4l2 device").arg(dev_name)); } else { emit display_error(tr("VIDIOC_QUERYCAP: %1").arg(QString(strerror(errno)))); } return -1; } if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { emit display_error(tr("%1 is no video capture device").arg(dev_name)); return -1; } if(!(cap.capabilities & V4L2_CAP_STREAMING)) { emit display_error(tr("%1 does not support streaming i/o").arg(dev_name)); return -1; } CLEAR(cropcap); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(0 == ioctl(fd, VIDIOC_CROPCAP, &cropcap)) { CLEAR(crop); crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; if(-1 == ioctl(fd, VIDIOC_S_CROP, &crop)) { if(EINVAL == errno) { // emit display_error(tr("VIDIOC_S_CROP not supported")); } else { emit display_error(tr("VIDIOC_S_CROP: %1").arg(QString(strerror(errno)))); return -1; } } } else { emit display_error(tr("VIDIOC_CROPCAP: %1").arg(QString(strerror(errno)))); return -1; } CLEAR(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_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if(-1 == ioctl(fd, VIDIOC_S_FMT, &fmt)) { emit display_error(tr("VIDIOC_S_FMT").arg(QString(strerror(errno)))); return -1; } if(-1 == init_mmap()) { return -1; } return 0; } int VideoDevice::init_mmap() { v4l2_requestbuffers req; CLEAR(req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if(-1 == ioctl(fd, VIDIOC_REQBUFS, &req)) { if(EINVAL == errno) { emit display_error(tr("%1 does not support memory mapping").arg(dev_name)); return -1; } else { emit display_error(tr("VIDIOC_REQBUFS %1").arg(QString(strerror(errno)))); return -1; } } if(req.count < 2) { emit display_error(tr("Insufficient buffer memory on %1").arg(dev_name)); return -1; } buffers = (buffer*)calloc(req.count, sizeof(*buffers)); if(!buffers) { emit display_error(tr("out of memory")); return -1; } for(n_buffers = 0; n_buffers < req.count; ++n_buffers) { v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if(-1 == ioctl(fd, VIDIOC_QUERYBUF, &buf)) { emit display_error(tr("VIDIOC_QUERYBUF: %1").arg(QString(strerror(errno)))); return -1; } buffers[n_buffers].length = buf.length; buffers[n_buffers].start = mmap(NULL, // start anywhere buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if(MAP_FAILED == buffers[n_buffers].start) { emit display_error(tr("mmap %1").arg(QString(strerror(errno)))); return -1; } } return 0; } int VideoDevice::start_capturing() { unsigned int i; for(i = 0; i < n_buffers; ++i) { v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory =V4L2_MEMORY_MMAP; buf.index = i; // fprintf(stderr, "n_buffers: %d\n", i); if(-1 == ioctl(fd, VIDIOC_QBUF, &buf)) { emit display_error(tr("VIDIOC_QBUF: %1").arg(QString(strerror(errno)))); return -1; } } v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(-1 == ioctl(fd, VIDIOC_STREAMON, &type)) { emit display_error(tr("VIDIOC_STREAMON: %1").arg(QString(strerror(errno)))); return -1; } return 0; } int VideoDevice::stop_capturing() { v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { emit display_error(tr("VIDIOC_STREAMOFF: %1").arg(QString(strerror(errno)))); return -1; } return 0; } int VideoDevice::uninit_device() { unsigned int i; for(i = 0; i < n_buffers; ++i) { if(-1 == munmap(buffers[i].start, buffers[i].length)) { emit display_error(tr("munmap: %1").arg(QString(strerror(errno)))); return -1; } } free(buffers); return 0; } int VideoDevice::get_frame(void **frame_buf, size_t* len) { v4l2_buffer queue_buf; CLEAR(queue_buf); queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queue_buf.memory = V4L2_MEMORY_MMAP; if(-1 == ioctl(fd, VIDIOC_DQBUF, &queue_buf)) { switch(errno) { case EAGAIN: // perror("dqbuf"); return -1; case EIO: return -1 ; default: emit display_error(tr("VIDIOC_DQBUF: %1").arg(QString(strerror(errno)))); return -1; } } *frame_buf = buffers[queue_buf.index].start; *len = buffers[queue_buf.index].length; index = queue_buf.index; return 0; } int VideoDevice::unget_frame() { if(index != -1) { v4l2_buffer queue_buf; CLEAR(queue_buf); queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; queue_buf.memory = V4L2_MEMORY_MMAP; queue_buf.index = index; if(-1 == ioctl(fd, VIDIOC_QBUF, &queue_buf)) { emit display_error(tr("VIDIOC_QBUF: %1").arg(QString(strerror(errno)))); return -1; } return 0; } return -1; }
#ifndef PROCESSIMAGE_H #define PROCESSIMAGE_H #include<QTcpServer> #include<QTcpSocket> #include <QtGui> #include "videodevice.h" class ProcessImage : public QWidget { Q_OBJECT public: ProcessImage(QWidget *parent=0); ~ProcessImage(); private: QPainter *painter; QLabel *label; QImage *frame; //QPixmap *frame; QTimer *timer; int rs; uchar *pp; uchar * p; QTcpServer *server; QTcpSocket *socket; int check; unsigned int len; int convert_yuv_to_rgb_pixel(int y, int u, int v); int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height); VideoDevice *vd; private slots: void paintEvent(QPaintEvent *); void display_error(QString err); void sendMessage(); }; #endif
#ifndef VIDEODEVICE_H #define VIDEODEVICE_H #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <asm/types.h> #include <linux/videodev2.h> #include <QString> #include <QObject> #define CLEAR(x) memset(&(x), 0, sizeof(x)) class VideoDevice : public QObject { Q_OBJECT public: VideoDevice(QString dev_name); //VideoDevice(); int open_device(); int close_device(); int init_device(); int start_capturing(); int stop_capturing(); int uninit_device(); int get_frame(void **, size_t*); int unget_frame(); private: int init_mmap(); struct buffer { void * start; size_t length; }; QString dev_name; int fd; buffer* buffers; unsigned int n_buffers; int index; signals: void display_error(QString); }; #endif // VIDEODEVICE_H
ARM端程序是在linux下开发的,需要在Linux下才能编译通过,不过建议先使用X11编译看到效果后,
之后在交叉编译,这样能更好的查错。因为交叉编译是看不到界面效果的。