📄 video1.cpp~
字号:
#include <qapplication.h> #include <qpushbutton.h> #include <qwidget.h> #include <qcolor.h> #include <qtimer.h> #include <qframe.h> #include <math.h> #include <qimage.h> #include <qpainter.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/videodev.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <string.h> #define ERR_FRAME_BUFFER 1 #define ERR_VIDEO_OPEN 2 #define ERR_VIDEO_GCAP 3 #define ERR_VIDEO_GPIC 4 #define ERR_VIDEO_SPIC 5 #define ERR_SYNC 6 #define ERR_FRAME_USING 7 #define ERR_GET_FRAME 8 #define RIGHT_GRAP_FRAME 9#define RIGHT_OPEN_VIDEO 10int screensize; #define V4L_FILE "/dev/video0" #define DEFAULT_PALETTE VIDEO_PALETTE_RGB565 class MyWidget : public QWidget { //O_OBJECT public: MyWidget( QWidget *parent=0, const char *name=0 ); int open_video(); int get_grab_frame(); void paintEvent(QPaintEvent *); private: QTimer *timer; QFrame *frame; unsigned short imageptr; int dep; int pal; int width; int height; // FrameBuffer 信息 struct fb_var_screeninfo vinfo; // FrameBuffer屏幕可变的信息 struct fb_fix_screeninfo finfo; // FrameBuffer固定不变的信息 //video4linux信息 int fd; struct video_capability capability; struct video_buffer buffer; struct video_picture picture; struct video_mmap map; struct video_mbuf mbuf; unsigned char *pmap; int frame_current;//what 's the frame number being captured currently? int frame_using[VIDEO_MAX_FRAME];//帧的状态没有采集还是等待结束? int screensize; }; MyWidget::MyWidget( QWidget *parent, const char *name ) : QWidget( parent, name ) { O_OBJECT; dep=16; pal=VIDEO_PALETTE_RGB565; width=320; height=240; frame_current = 0; frame_using[0] = 0; frame_using[1] = 0; setCaption("Video"); frame=new QFrame(this,"frame"); frame->setBackgroundColor(black); frame->setGeometry(QRect(40,40,402,252)); QTimer *timer=new QTimer(this,"timer"); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(update())); timer->start(30); printf("timer is using\n"); } int MyWidget::get_grab_frame() { if (frame_using[frame_current]) { fprintf(stderr, "get_grab_frame: frame %d is already used.\n", frame_current); return ERR_FRAME_USING; } map.frame = frame_current; if (ioctl(fd, VIDIOCMCAPTURE, &(map)) < 0) { perror("v4l_grab_frame"); return ERR_GET_FRAME; } //置为采集忙状态 frame_using[frame_current] = 1; if (ioctl(fd, VIDIOCSYNC, &(frame_current)) < 0) // 等待帧同步 { perror("v4l_grab_sync"); return ERR_SYNC; } frame_using[frame_current] = 0 ;//采集完毕置0 return RIGHT_GRAP_FRAME; } int MyWidget::open_video() { // 打开视频设备 if ((fd = open(V4L_FILE, O_RDWR)) < 0) { perror("v4l_open:"); return ERR_VIDEO_OPEN; } printf("=============Open Video Success======================="); // 获取设备 if (ioctl(fd, VIDIOCGCAP, &(capability)) < 0) { perror("v4l_get_capability:"); return ERR_VIDEO_GCAP; } printf("Camera found: %s,maxwidth:%d,maxheight:%d,minwidth:%d,minheight:%d \n",capability.name,capability.maxwidth,capability.maxheight,capability.minwidth,capability.minheight); printf("=============Get Device Success======================="); // 获取图象 if (ioctl(fd, VIDIOCGPICT, &(picture)) < 0) { perror("v4l_get_picture"); return ERR_VIDEO_GPIC; } printf("=============Get Picture Success======================="); printf("=====Capture depth:%d,Palette:%d,brightness:%d,hue:%d,contrast:%d===============\n",picture.depth,picture.palette,picture.brightness,picture.hue,picture.contrast); // 设置图象 picture.palette = pal; // 调色板 picture.depth = dep; // 像素深度 map.format =pal; if (ioctl(fd, VIDIOCSPICT, &(picture)) < 0) { perror("v4l_set_palette"); return ERR_VIDEO_SPIC; } printf("=====Capture depth:%d,Palette:%d,brightness:%d,hue:%d,contrast:%d===============\n",picture.depth,picture.palette,picture.brightness,picture.hue,picture.contrast); memset (&(mbuf), 0, sizeof(mbuf)); // 获取摄像头缓冲区信息 if (ioctl(fd, VIDIOCGMBUF, &(mbuf)) < 0) { perror("v4l_get_mbuf"); return -1; } printf ("VIDIOCGMBUF size %d frames %d offets[0]=%d offsets[1]=%d\n",mbuf.size, mbuf.frames, mbuf.offsets[0], mbuf.offsets[1]); // 建立设备内存影射,将视频设备影射到内存空间 pmap = (unsigned char *) (mmap(NULL, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)); if ( pmap < 0) { perror("v4l_mmap_init:map"); return -1; } map.width = width; // width; map.height = height; // height; map.format = picture.palette; printf("The video device was opened successfully.\n"); return RIGHT_OPEN_VIDEO;} void MyWidget::paintEvent(QPaintEvent *) { int x, y; int i = 0; QRgb *point; int r, g, b; int imgwidth=402; int imgheight=252; //创建该PaintEvent的操作对象paint //该对象为静态对象,不需要每次paint都创建一个QPainter static QPainter paint(frame); //读取内存内容,创建QImage对象 QImage *image = new QImage(); //该步很重要,设置标志 //让QWidget在更新窗体时,不擦除原来的窗体 //这样可以避免闪屏 setWFlags(getWFlags() | Qt::WRepaintNoErase); //begin graping picture get_grab_frame(); imageptr = (unsigned short) ( pmap + mbuf.offsets[frame_current]); frame_current ^= 1;//两帧采集不是0就是1 if(image->create(imgwidth, imgheight, 32, 0, QImage::IgnoreEndian)) { for(x = 0; x < imgheight; x++) { for(y = 0; y < imgwidth; y++) { r =(imageptr&0xf800)>>11; g = (imageptr&0x07e0)>>5; b = imageptr&0x001f; point = (QRgb *)image->scanLine(x)+y; *point = qRgb(r, g, b); i++; } } } //开始绘图 paint.drawImage(0, 0, *image); // paint.drawImage(QRect(40,34,402,252), *image); } int main( int argc, char **argv ) { QApplication a( argc, argv ); MyWidget *w=new MyWidget(0); w->setGeometry( 10, 20, 480, 320 ); a.setMainWidget( w ); w->show(); w->open_video(); //a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); return a.exec(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -