|
@@ -1,5 +1,6 @@
|
|
|
#include <QCoreApplication>
|
|
|
#include <thread>
|
|
|
+#include <QMutex>
|
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
#include <opencv2/core.hpp>
|
|
@@ -13,12 +14,26 @@
|
|
|
|
|
|
#include <QTime>
|
|
|
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <unistd.h>
|
|
|
+
|
|
|
+#include <sys/types.h> // 下面四个头文件是linux系统编程特有的
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <sys/ioctl.h>
|
|
|
+#include <sys/mman.h>
|
|
|
+#include <fcntl.h>
|
|
|
+
|
|
|
+#include <linux/videodev2.h> // 操作摄像头设备
|
|
|
+
|
|
|
#include "modulecomm.h"
|
|
|
#include "rawpic.pb.h"
|
|
|
#include "xmlparam.h"
|
|
|
|
|
|
#include "ivversion.h"
|
|
|
|
|
|
+#define COUNT 8 // 缓冲区个数
|
|
|
+
|
|
|
void * gpa;
|
|
|
|
|
|
int gindex = 0;
|
|
@@ -32,7 +47,17 @@ std::string gstrcamera = "";
|
|
|
|
|
|
std::string gmsgname = "usbpic";
|
|
|
|
|
|
-std::string gstrdevname = "video0";
|
|
|
+std::string gstrdevname = "/dev/video5";
|
|
|
+
|
|
|
+
|
|
|
+QMutex gMutexRawData;
|
|
|
+char * gRawData;
|
|
|
+int gnLenRaw;
|
|
|
+bool gbUpdate = false;
|
|
|
+
|
|
|
+QMutex gMutexCompress;
|
|
|
+cv::Mat gMatPic;
|
|
|
+bool gbUpdateMat = false;
|
|
|
|
|
|
|
|
|
#ifndef CV_CAP_PROP_FRAME_WIDTH
|
|
@@ -186,7 +211,126 @@ void VideoThread(int n)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int test()
|
|
|
+void threadCompress()
|
|
|
+{
|
|
|
+ cv::Mat mat1;
|
|
|
+
|
|
|
+ int nserbufsize = 20000000;
|
|
|
+
|
|
|
+ char * strser = new char[nserbufsize];
|
|
|
+
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ if(gbUpdateMat == false)
|
|
|
+ {
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ gMutexCompress.lock();
|
|
|
+ gMatPic.copyTo(mat1);
|
|
|
+ gbUpdateMat = false;
|
|
|
+ gMutexCompress.unlock();
|
|
|
+
|
|
|
+ iv::vision::rawpic pic;
|
|
|
+
|
|
|
+ qint64 time = QDateTime::currentMSecsSinceEpoch();
|
|
|
+ QTime xg;
|
|
|
+ xg.start();
|
|
|
+ pic.set_time(time);
|
|
|
+ pic.set_index(gindex);gindex++;
|
|
|
+
|
|
|
+
|
|
|
+ pic.set_elemsize(mat1.elemSize());
|
|
|
+ pic.set_width(mat1.cols);
|
|
|
+ pic.set_height(mat1.rows);
|
|
|
+ pic.set_mattype(mat1.type());
|
|
|
+
|
|
|
+// cv::Mat matcompress;
|
|
|
+// cv::resize(mat1,matcompress,cv::Size(640,360));
|
|
|
+
|
|
|
+
|
|
|
+ std::vector<int> param = std::vector<int>(2);
|
|
|
+ param[0] = CV_IMWRITE_JPEG_QUALITY;
|
|
|
+ param[1] = gcompquality; // default(95) 0-100
|
|
|
+ std::vector<unsigned char> buff;
|
|
|
+ if(gcompress == 1)
|
|
|
+ {
|
|
|
+ cv::imencode(".jpg", mat1, buff, param);
|
|
|
+// cv::imencode(".jpg", matcompress, buff, param);
|
|
|
+ pic.set_picdata(buff.data(),buff.size());
|
|
|
+ buff.clear();
|
|
|
+ pic.set_type(2);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pic.set_picdata(mat1.data,mat1.rows*mat1.cols*mat1.elemSize());
|
|
|
+// pic.set_picdata(matcompress.data,matcompress.rows*matcompress.cols*matcompress.elemSize());
|
|
|
+ pic.set_type(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ int nSize = pic.ByteSize();
|
|
|
+
|
|
|
+ // char * strser = new char[nSize];
|
|
|
+ bool bser = pic.SerializeToArray(strser,nSize);
|
|
|
+ qDebug("pac time is %d size is %d",xg.elapsed(),nSize);
|
|
|
+
|
|
|
+ // iv::modulecomm::ModuleSendMsg(gpa,str.data(),str.length());
|
|
|
+ if(bser)iv::modulecomm::ModuleSendMsg(gpa,strser,nSize);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<"usbcamera "<< "serialize error. "<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void threadConvert()
|
|
|
+{
|
|
|
+ char * strRawData = new char[gwidth*gheight*4];
|
|
|
+ int nlen = 0;
|
|
|
+ IplImage *srcImg;
|
|
|
+
|
|
|
+
|
|
|
+ srcImg = cvCreateImage(cvSize(gwidth, gheight), 8, 3);
|
|
|
+ cvZero(srcImg);
|
|
|
+ cv::Mat mat1(cvSize(gwidth, gheight), CV_8UC3,srcImg->imageData) ;//(cvSize(WIDTH, HEIGHT), CV_8UC3);//, frame.imageData);;
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ if(gbUpdate == false)
|
|
|
+ {
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ gMutexRawData.lock();
|
|
|
+ nlen = gnLenRaw;
|
|
|
+ memcpy(strRawData,gRawData,gnLenRaw);
|
|
|
+ gbUpdate = false;
|
|
|
+ gMutexRawData.unlock();
|
|
|
+
|
|
|
+ if(nlen > 0)
|
|
|
+ {
|
|
|
+ QTime x;
|
|
|
+ x.start();
|
|
|
+ cv::cvtColor(cv::Mat(gheight * 3 / 2, gwidth, CV_8U,strRawData), mat1,
|
|
|
+ cv::COLOR_YUV2BGR_NV12);
|
|
|
+ qDebug(" 2rgb tims is %d",x.elapsed());
|
|
|
+
|
|
|
+
|
|
|
+ gMutexCompress.lock();
|
|
|
+ mat1.copyTo(gMatPic);
|
|
|
+ gbUpdateMat = true;
|
|
|
+ gMutexCompress.unlock();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int threadcapture()
|
|
|
{
|
|
|
unsigned char *datas[COUNT]; // 缓冲区数据地址
|
|
|
int ret, i;
|
|
@@ -203,9 +347,9 @@ int test()
|
|
|
/* 第二步:设置捕捉图片帧格式 */
|
|
|
struct v4l2_format format;
|
|
|
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; //V4L2_BUF_TYPE_VIDEO_CAPTURE; // 操作类型为获取图片
|
|
|
- format.fmt.pix.width = WIDTH; // 图片的宽度
|
|
|
- format.fmt.pix.height = HEIGHT; // 图片的高度
|
|
|
- format.fmt.pix.pixelformat = FMT; // 图片格式
|
|
|
+ format.fmt.pix.width = gwidth; // 图片的宽度
|
|
|
+ format.fmt.pix.height = gheight; // 图片的高度
|
|
|
+ format.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; // 图片格式
|
|
|
format.fmt.pix_mp.field = V4L2_FIELD_NONE; // 逐行扫描
|
|
|
ret = ioctl(fd, VIDIOC_S_FMT, &format); // 进行设置(Set)
|
|
|
if (-1 == ret)
|
|
@@ -223,7 +367,7 @@ int test()
|
|
|
close(fd);
|
|
|
return -3;
|
|
|
}
|
|
|
- if (format.fmt.pix.pixelformat == FMT)
|
|
|
+ if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
|
|
|
{
|
|
|
printf("ioctl VIDIOC_S_FMT sucessful\n");
|
|
|
}
|
|
@@ -321,14 +465,15 @@ int test()
|
|
|
|
|
|
|
|
|
|
|
|
- srcImg = cvCreateImage(cvSize(WIDTH, HEIGHT), 8, 3);
|
|
|
+ srcImg = cvCreateImage(cvSize(gwidth, gheight), 8, 3);
|
|
|
cvZero(srcImg);
|
|
|
- cv::Mat destination(cvSize(WIDTH, HEIGHT), CV_8UC3,srcImg->imageData) ;//(cvSize(WIDTH, HEIGHT), CV_8UC3);//, frame.imageData);;
|
|
|
+ cv::Mat destination(cvSize(gwidth, gheight), CV_8UC3,srcImg->imageData) ;//(cvSize(WIDTH, HEIGHT), CV_8UC3);//, frame.imageData);;
|
|
|
|
|
|
int k;
|
|
|
- int nlen = WIDTH * HEIGHT *3;
|
|
|
- char * strRGB = new char[nlen];
|
|
|
- for(k=0;k<100000;k++)
|
|
|
+ int nlen = gwidth * gheight *3;
|
|
|
+
|
|
|
+// for(k=0;k<100000;k++)
|
|
|
+ while(1)
|
|
|
{
|
|
|
struct v4l2_buffer buf;
|
|
|
memset(&buf, 0, sizeof(buf));
|
|
@@ -348,44 +493,26 @@ int test()
|
|
|
return -8;
|
|
|
}
|
|
|
|
|
|
- qDebug("index is %d",buff.index);
|
|
|
- QTime x;
|
|
|
- x.start();
|
|
|
- // nv122rgb((char *)datas[buff.index],strRGB,nlen/3);
|
|
|
-
|
|
|
- // nv122rgb((char *)datas[buff.index],(unsigned char *)srcImg->imageData,nlen/3);
|
|
|
+ gMutexRawData.lock();
|
|
|
+ memcpy(gRawData,(char *)datas[buff.index],gheight*gwidth*3/2);
|
|
|
+ gbUpdate = true;
|
|
|
+ gnLenRaw = gheight * gwidth *3/2;
|
|
|
+ gMutexRawData.unlock();
|
|
|
|
|
|
-
|
|
|
- cv::cvtColor(cv::Mat(HEIGHT * 3 / 2, WIDTH, CV_8U,(char *)datas[buff.index]), destination,
|
|
|
- cv::COLOR_YUV2BGR_NV12);
|
|
|
- // clipNv12ToJpgFile("/home/linaro/code/common/testv4l2/1.jpg",datas[buff.index],WIDTH,HEIGHT);
|
|
|
- // NV12_To_RGB(WIDTH,HEIGHT,datas[buff.index],(unsigned char *)srcImg->imageData);
|
|
|
- qDebug(" 2rgb tims is %d",x.elapsed());
|
|
|
+ qDebug("index is %d",buff.index);
|
|
|
+// QTime x;
|
|
|
+// x.start();
|
|
|
+// cv::cvtColor(cv::Mat(gheight * 3 / 2, gwidth, CV_8U,(char *)datas[buff.index]), destination,
|
|
|
+// cv::COLOR_YUV2BGR_NV12);
|
|
|
+// qDebug(" 2rgb tims is %d",x.elapsed());
|
|
|
ioctl(fd, VIDIOC_QBUF, &buff);
|
|
|
qDebug("%d:%ld",k,QDateTime::currentMSecsSinceEpoch());
|
|
|
|
|
|
- cvNamedWindow("YUV2RGB", 1);
|
|
|
- IplImage * img;
|
|
|
-// *img = destination;
|
|
|
- // *img = IplImage(destination);
|
|
|
-
|
|
|
-// cvShowImage("YUV2RGB", img);
|
|
|
- // cvShowImage("YUV2RGB", &destination);
|
|
|
- cvShowImage("YUV2RGB", srcImg);
|
|
|
- cvWaitKey(1);
|
|
|
+// cvNamedWindow("YUV2RGB", 1);
|
|
|
+// cvShowImage("YUV2RGB", srcImg);
|
|
|
+// cvWaitKey(1);
|
|
|
}
|
|
|
|
|
|
- /* 第八步:从退出队列的缓冲区中获取数据并保存到文件中 */
|
|
|
- FILE *fl;
|
|
|
- fl = fopen("./my.yuyv", "w");
|
|
|
- if (NULL == fl)
|
|
|
- {
|
|
|
- fprintf(stderr, "open write file failed.");
|
|
|
- }
|
|
|
- fwrite(datas[buff.index], buff.bytesused, 1, fl);
|
|
|
-
|
|
|
- fclose(fl); // 记得关闭已打开的文件
|
|
|
- close(fd); // 记得关闭已打开的设备
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -393,19 +520,20 @@ int test()
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
- showversion("driver_camera_usb");
|
|
|
+ showversion("driver_camera_rk3399");
|
|
|
QCoreApplication a(argc, argv);
|
|
|
|
|
|
+ gRawData = new char[20000000];
|
|
|
QString strpath = QCoreApplication::applicationDirPath();
|
|
|
// QString apppath = strpath;
|
|
|
if(argc < 2)
|
|
|
- strpath = strpath + "/driver_camera_usb.xml";
|
|
|
+ strpath = strpath + "/driver_camera_rk3399.xml";
|
|
|
else
|
|
|
strpath = argv[1];
|
|
|
std::cout<<strpath.toStdString()<<std::endl;
|
|
|
iv::xmlparam::Xmlparam xp(strpath.toStdString());
|
|
|
|
|
|
- std::string xmlmsgname = xp.GetParam("msgname","compresspic");
|
|
|
+ std::string xmlmsgname = xp.GetParam("msgname","image00");
|
|
|
gmsgname = xmlmsgname;
|
|
|
std::string strwidth = xp.GetParam("width","1280");
|
|
|
std::string strheight = xp.GetParam("height","720");
|
|
@@ -414,7 +542,7 @@ int main(int argc, char *argv[])
|
|
|
std::string strcompquality = xp.GetParam("compquality","95");
|
|
|
gcompquality = atoi(strcompquality.data());
|
|
|
|
|
|
- gstrcamera = xp.GetParam("cameraname","video0");
|
|
|
+ gstrcamera = xp.GetParam("cameraname","/dev/video5");
|
|
|
|
|
|
gwidth = atoi(strwidth.data());
|
|
|
gheight = atoi(strheight.data());
|
|
@@ -422,7 +550,15 @@ int main(int argc, char *argv[])
|
|
|
gcompress = atoi(strcompress.data());
|
|
|
|
|
|
gpa = iv::modulecomm::RegisterSend(gmsgname.data(),20000000,1);
|
|
|
- std::thread * mthread = new std::thread(VideoThread,0);
|
|
|
+ std::thread * mthread = new std::thread(threadcapture) ;//new std::thread(VideoThread,0);
|
|
|
+
|
|
|
+ std::thread * conthread = new std::thread(threadConvert);
|
|
|
+
|
|
|
+ std::thread * compressthread = new std::thread(threadCompress);
|
|
|
+
|
|
|
+ (void)mthread;
|
|
|
+ (void)conthread;
|
|
|
+ (void)compressthread;
|
|
|
|
|
|
return a.exec();
|
|
|
}
|