前言
参考了一些文章如下:
V4L2相关:点击跳转
其它文章:
    Qt—Linux平台Qt5用V4L2读取摄像头,实现实时画面和拍照
    V4L2+Qt5实现摄像头视频采集以及参数控制(源码学习版)_虾米小小小的博客-CSDN博客
一、项目功能简介
- 监控画面显示及暂停 
- 画面录制 
- 录制视频回放 
- 录制文件以时间段为名保存 
二、界面展示

三、项目实现
1、整体流程

2、功能实现
这里只展示了部分代码,完整代码请到最下方的链接下载
标志信息
| 12
 3
 4
 5
 6
 7
 
 | bool stop_flag;             bool record_flag;
 bool replay_flag;
 FILE *fp,*fp_replay;
 unsigned char pic[153600];
 unsigned char *display;
 int count;
 
 | 
初始化
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | replay_pp = (unsigned char *)malloc(320 * 240* 3 * sizeof(char));v = (unsigned char *)malloc(153600);
 replay_frame = new QImage(pp,320,240,QImage::Format_RGB888);
 
 pp = (unsigned char *)malloc(320 * 240* 3 * sizeof(char));
 painter = new QPainter(this);
 frame = new QImage(pp,320,240,QImage::Format_RGB888);
 stop_flag = false;
 record_flag = false;
 replay_flag = false;
 fp = NULL;
 label = new QLabel();
 btn_stop = new QPushButton(this);
 btn_replay = new QPushButton(this);
 btn_record = new QPushButton(this);
 vd = new VideoDevice(tr("/dev/video0"));
 count = 0;
 
 connect(vd, SIGNAL(display_error(QString)), this,SLOT(display_error(QString)));
 rs = vd->open_device();
 
 | 
停止功能
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | void ProcessImage::on_btn_stop_clicked(){
 qDebug()<<"on_btn_stop_clicked";
 if(!stop_flag)
 {
 stop_flag = true;
 btn_stop->setText("Display");
 }
 else
 {
 stop_flag = false;
 btn_stop->setText("Stop");
 }
 }
 
 | 
录制功能
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | void ProcessImage::on_btn_record_clicked(){
 qDebug()<<"on_btn_record_clicked";
 gettimeofday(&tv,NULL);
 sec=tv.tv_sec;
 min=tv.tv_sec/60;
 localtime_r((time_t*)&sec,&cur_tm);
 snprintf(cur_time,20,"%d.%02d.%02d %02d:%02d:%02d",cur_tm.tm_year+1900,cur_tm.tm_mon+1,cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min,cur_tm.tm_sec);
 
 if(!record_flag)
 {
 fp = fopen("/record_buf.yuv","wb+");
 if(fp != NULL){qDebug()<<"fp open success";}
 else{qDebug()<<"fp open fail";}
 str1 = QString::fromLocal8Bit(cur_time);
 qDebug()<<str1;
 record_flag = true;
 btn_record->setText("Stop_record");
 }
 else
 {
 if(fp != NULL)
 {
 fclose(fp);
 qDebug()<<"fp closed";
 }
 str2= QString::fromLocal8Bit(cur_time);
 qDebug()<<str2;
 name = "/"+str1 + "-"+ str2;
 qDebug()<<name;
 rename("/record_buf.yuv",name.toLocal8Bit());
 record_flag = false;
 btn_record->setText("Record");
 }
 }
 
 | 
回放功能
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | void ProcessImage::on_btn_replay_clicked(){
 qDebug()<<"on_btn_replay_clicked";
 if(!replay_flag)
 {
 fp_replay = fopen(name.toLocal8Bit(),"rb+");
 if(fp_replay != NULL){qDebug()<<"fp_replay open success";}
 else{qDebug()<<"fp_replay open fail";}
 replay_flag = true;
 btn_replay->setText("Over_replay");
 }
 else
 {
 if(fp_replay != NULL)
 {
 fclose(fp_replay);
 qDebug()<<"fp_replay open fail";
 }
 btn_replay->setText("Replay");
 replay_flag = false;
 }
 }
 
 | 
图像获取与刷新
这里值得一提的是,下方代码的分频系数(5)可以用一个变量来替换,再加上一个按钮来控制这个变量的值,这样就可以实现回放视频的加速减速了。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 
 | void ProcessImage::paintEvent(QPaintEvent *){
 if(!stop_flag)
 {
 if(replay_flag)
 {
 count ++;
 if(count == 5)
 {
 if(fread(pic,1,153600,fp_replay)>=153600)
 {
 display = pic;
 }
 else
 {
 qDebug()<<"Read over";
 rewind(fp_replay);
 }
 count = 0;
 }
 }
 else
 {
 rs = vd->get_frame((void **)&p,(size_t *)&len);
 if(record_flag)
 {
 qDebug()<<"Recording";
 fwrite(p,153600,1,fp);
 }
 qDebug()<<"Displaying";
 display = (unsigned char *)p;
 
 }
 
 if(!replay_flag || count == 0)
 {
 convert_yuv_to_rgb_buffer(display,pp,320,240);
 frame->loadFromData((uchar *)pp,320 * 240 * 3 * sizeof(char));
 label->setPixmap(QPixmap::fromImage(*frame,Qt::AutoColor));
 }
 
 if(!replay_flag)
 {
 rs = vd->unget_frame();
 }
 }
 }
 
 | 
需要注意的一点是该程序在虚拟机上运行存在一点问题,无法正常运行,但在开发板上可以正常运行。有问题可以在评论区留言,最后在这里留下源代码下载地址
链接:https://pan.baidu.com/s/1_E1sUcUqxjIg5E-kyeMbVg
提取码:v4l2