| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- #include <QCoreApplication>
- #include <unistd.h>
- #include <sys/time.h>
- #include <thread>
- #include <queue>
- #include <string>
- #include <stdio.h>
- #include <mutex>
- #include <v4l2cam.hpp>
- #include "libyuv.h"
- #include "xmlparam.h"
- static bool gbRun = true;
- #define MAX_WIDHT 4096
- #define MAX_HEIGHT 2160
- #include "modulecomm.h"
- #include <QMutex>
- #include <QWaitCondition>
- #include <thread>
- #include "zerobuffer.h"
- ZeroBuffer * gbuffer;
- extern char * gstrbuffer;
- extern QMutex gMutexLock;
- extern bool gbNewData;
- extern QWaitCondition gwc;
- static char * gstrwidth ="1280";
- static char * gstrheight = "720";
- int gnwidth,gnheight;
- extern void StartNVENC(char * strwidth,char * strheight);
- extern bool gbNewOut;
- extern QWaitCondition gwcout;
- extern char * gstrout;
- extern QMutex gWaitMutexout;
- extern QMutex gMutexout;
- extern int gnoutsize ;
- void * gpaout;
- void yuv_rotate_180(uint8_t* yuvbuf, uint8_t* dstbuf,int width,int height){
- int idx = 0;
- //旋转180:将右下角的点作为第一个点,从右往左,从下往上取点
- //Y 宽:[0,w-1] 高:[0,h-1]
- for (int i = height-1; i >=0; i--){
- for (int j = width-1 ; j >= 0; j--){
- dstbuf[idx++] = *(yuvbuf+(i*width+j));
- }
- }
- uint8_t* uheader = yuvbuf + width*height;
- //U
- for (int i = height/2 - 1; i >= 0; i--){
- for (int j = width/2-1 ; j >= 0; j--){
- dstbuf[idx++] = *(uheader + (i*width / 2 + j));
- }
- }
- uint8_t* vheader = uheader + width*height/4;
- //V
- for (int i = height / 2 - 1; i >= 0; i--){
- for (int j = width / 2-1 ; j >=0; j--){
- dstbuf[idx++] = *(vheader + (i*width / 2 + j));
- }
- }
- }
- void threadcap( std::string dev,std::string name,std::int32_t width,std::int32_t height,bool bRotate)
- {
- printf("width=%d,height=%d\n",width,height);
- CV4l2Cam cam(dev,width,height);
- do{
- if(cam.Init() < 0)
- {
- printf("camera init failed and retry after 3s\n");
- sleep(3);
- }
- else
- {
- break;
- }
- }while(1);
- cam.startAcquire();
- static unsigned char yuv[3*MAX_HEIGHT*MAX_WIDHT/2];
- unsigned char * yuvrotate = new unsigned char[3*MAX_HEIGHT*MAX_WIDHT/2];
- unsigned char *yuyv = NULL;
- int yuyvlen = 0;
- while(1)
- {
- if(cam.GrabImg(yuyv,yuyvlen) == 0)
- {
- libyuv::YUY2ToI420(yuyv,2*width,
- yuv,width,
- yuv+width*height,width/2,
- yuv+5*width*height/4,width/2,
- width,
- height);
- // std::cout<<" grab a img. time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<"ms"<<std::endl;
- char * p;
- int nrtn = gbuffer->RequireBuffer(&p,1000);
- if(nrtn < 0)
- {
- std::cout<<" Get Zero Buffer Fail."<<std::endl;
- continue;
- }
- if(bRotate == false)
- memcpy(p,(char *)yuv,width*height*3/2);
- else
- {
- // int64_t time1 = std::chrono::system_clock::now().time_since_epoch().count();
- yuv_rotate_180(yuv,yuvrotate,width,height);
- // int64_t time2 = std::chrono::system_clock::now().time_since_epoch().count();
- // std::cout<<" rotate use "<<(time2 - time1)/1000<<" us "<<std::endl;
- memcpy(p,(char *)yuvrotate,width*height*3/2);
- }
- gbuffer->UpdateDataSize(width*height*3/2);
- gbuffer->ReleaseBuffer();
- // imgpub.Send(yuv,3*width*height/2);
- }
- }
- cam.stopAcquire();
- cam.Release();
- }
- void threadout()
- {
- char * strout = new char[10000000];
- int nout = 0;
- while(1)
- {
- gWaitMutexout.lock();
- gwcout.wait(&gWaitMutexout,10);
- gWaitMutexout.unlock();
- if(gbNewOut)
- {
- gMutexout.lock();
- memcpy(strout, gstrout,gnoutsize);
- nout = gnoutsize;
- gbNewOut = false;
- gMutexout.unlock();
- // std::cout<<"send out. "<<std::endl;
- iv::modulecomm::ModuleSendMsg(gpaout,strout,nout);
- }
- }
- }
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- QString strpath = QCoreApplication::applicationDirPath();
- // QString apppath = strpath;
- if(argc < 2)
- strpath = strpath + "/driver_camera_tz.xml";
- else
- strpath = argv[1];
- std::cout<<strpath.toStdString()<<std::endl;
- std::string dev; //dev
- std::string name; //设备名称
- std::int32_t width;
- std::int32_t height;
- std::string strframename;
- int ngop;
- int nbitrate;
- bool bRotate;
- iv::xmlparam::Xmlparam xp(strpath.toStdString());
- xp.GetParam("dev", dev, "/dev/video4");
- xp.GetParam("name", name, "camera0");
- xp.GetParam("width", width, 1280);
- xp.GetParam("height", height, 720);
- xp.GetParam("framename",strframename,"h264frame");
- xp.GetParam("bitrate",nbitrate,2000000);
- xp.GetParam("GOP",ngop,10);
- xp.GetParam("Rotate",bRotate,false);
- gbuffer = new ZeroBuffer(30000000);
- gstrbuffer = new char[30000000];
- gstrout = new char[10000000];
- gnwidth = width;
- gnheight = height;
- gpaout = iv::modulecomm::RegisterSend(strframename.data(),1000000,1);
- std::thread * pthreadcap = new std::thread(threadcap,dev,name,width,height,bRotate);
- void * pthreadout = new std::thread(threadout);
- (void )pthreadcap;
- (void)pthreadout;
- StartNVENC(gstrwidth,gstrheight);
- return a.exec();
- }
|