main.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include <QCoreApplication>
  2. #include <unistd.h>
  3. #include <sys/time.h>
  4. #include <thread>
  5. #include <queue>
  6. #include <string>
  7. #include <stdio.h>
  8. #include <mutex>
  9. #include <v4l2cam.hpp>
  10. #include "libyuv.h"
  11. #include "xmlparam.h"
  12. static bool gbRun = true;
  13. #define MAX_WIDHT 4096
  14. #define MAX_HEIGHT 2160
  15. #include "modulecomm.h"
  16. #include <QMutex>
  17. #include <QWaitCondition>
  18. #include <thread>
  19. #include "zerobuffer.h"
  20. ZeroBuffer * gbuffer;
  21. extern char * gstrbuffer;
  22. extern QMutex gMutexLock;
  23. extern bool gbNewData;
  24. extern QWaitCondition gwc;
  25. static char * gstrwidth ="1280";
  26. static char * gstrheight = "720";
  27. int gnwidth,gnheight;
  28. extern void StartNVENC(char * strwidth,char * strheight);
  29. extern bool gbNewOut;
  30. extern QWaitCondition gwcout;
  31. extern char * gstrout;
  32. extern QMutex gWaitMutexout;
  33. extern QMutex gMutexout;
  34. extern int gnoutsize ;
  35. void * gpaout;
  36. void yuv_rotate_180(uint8_t* yuvbuf, uint8_t* dstbuf,int width,int height){
  37. int idx = 0;
  38. //旋转180:将右下角的点作为第一个点,从右往左,从下往上取点
  39. //Y 宽:[0,w-1] 高:[0,h-1]
  40. for (int i = height-1; i >=0; i--){
  41. for (int j = width-1 ; j >= 0; j--){
  42. dstbuf[idx++] = *(yuvbuf+(i*width+j));
  43. }
  44. }
  45. uint8_t* uheader = yuvbuf + width*height;
  46. //U
  47. for (int i = height/2 - 1; i >= 0; i--){
  48. for (int j = width/2-1 ; j >= 0; j--){
  49. dstbuf[idx++] = *(uheader + (i*width / 2 + j));
  50. }
  51. }
  52. uint8_t* vheader = uheader + width*height/4;
  53. //V
  54. for (int i = height / 2 - 1; i >= 0; i--){
  55. for (int j = width / 2-1 ; j >=0; j--){
  56. dstbuf[idx++] = *(vheader + (i*width / 2 + j));
  57. }
  58. }
  59. }
  60. void threadcap( std::string dev,std::string name,std::int32_t width,std::int32_t height,bool bRotate)
  61. {
  62. printf("width=%d,height=%d\n",width,height);
  63. CV4l2Cam cam(dev,width,height);
  64. do{
  65. if(cam.Init() < 0)
  66. {
  67. printf("camera init failed and retry after 3s\n");
  68. sleep(3);
  69. }
  70. else
  71. {
  72. break;
  73. }
  74. }while(1);
  75. cam.startAcquire();
  76. static unsigned char yuv[3*MAX_HEIGHT*MAX_WIDHT/2];
  77. unsigned char * yuvrotate = new unsigned char[3*MAX_HEIGHT*MAX_WIDHT/2];
  78. unsigned char *yuyv = NULL;
  79. int yuyvlen = 0;
  80. while(1)
  81. {
  82. if(cam.GrabImg(yuyv,yuyvlen) == 0)
  83. {
  84. libyuv::YUY2ToI420(yuyv,2*width,
  85. yuv,width,
  86. yuv+width*height,width/2,
  87. yuv+5*width*height/4,width/2,
  88. width,
  89. height);
  90. // std::cout<<" grab a img. time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<"ms"<<std::endl;
  91. char * p;
  92. int nrtn = gbuffer->RequireBuffer(&p,1000);
  93. if(nrtn < 0)
  94. {
  95. std::cout<<" Get Zero Buffer Fail."<<std::endl;
  96. continue;
  97. }
  98. if(bRotate == false)
  99. memcpy(p,(char *)yuv,width*height*3/2);
  100. else
  101. {
  102. // int64_t time1 = std::chrono::system_clock::now().time_since_epoch().count();
  103. yuv_rotate_180(yuv,yuvrotate,width,height);
  104. // int64_t time2 = std::chrono::system_clock::now().time_since_epoch().count();
  105. // std::cout<<" rotate use "<<(time2 - time1)/1000<<" us "<<std::endl;
  106. memcpy(p,(char *)yuvrotate,width*height*3/2);
  107. }
  108. gbuffer->UpdateDataSize(width*height*3/2);
  109. gbuffer->ReleaseBuffer();
  110. // imgpub.Send(yuv,3*width*height/2);
  111. }
  112. }
  113. cam.stopAcquire();
  114. cam.Release();
  115. }
  116. void threadout()
  117. {
  118. char * strout = new char[10000000];
  119. int nout = 0;
  120. while(1)
  121. {
  122. gWaitMutexout.lock();
  123. gwcout.wait(&gWaitMutexout,10);
  124. gWaitMutexout.unlock();
  125. if(gbNewOut)
  126. {
  127. gMutexout.lock();
  128. memcpy(strout, gstrout,gnoutsize);
  129. nout = gnoutsize;
  130. gbNewOut = false;
  131. gMutexout.unlock();
  132. // std::cout<<"send out. "<<std::endl;
  133. iv::modulecomm::ModuleSendMsg(gpaout,strout,nout);
  134. }
  135. }
  136. }
  137. int main(int argc, char *argv[])
  138. {
  139. QCoreApplication a(argc, argv);
  140. QString strpath = QCoreApplication::applicationDirPath();
  141. // QString apppath = strpath;
  142. if(argc < 2)
  143. strpath = strpath + "/driver_camera_tz.xml";
  144. else
  145. strpath = argv[1];
  146. std::cout<<strpath.toStdString()<<std::endl;
  147. std::string dev; //dev
  148. std::string name; //设备名称
  149. std::int32_t width;
  150. std::int32_t height;
  151. std::string strframename;
  152. int ngop;
  153. int nbitrate;
  154. bool bRotate;
  155. iv::xmlparam::Xmlparam xp(strpath.toStdString());
  156. xp.GetParam("dev", dev, "/dev/video4");
  157. xp.GetParam("name", name, "camera0");
  158. xp.GetParam("width", width, 1280);
  159. xp.GetParam("height", height, 720);
  160. xp.GetParam("framename",strframename,"h264frame");
  161. xp.GetParam("bitrate",nbitrate,2000000);
  162. xp.GetParam("GOP",ngop,10);
  163. xp.GetParam("Rotate",bRotate,false);
  164. gbuffer = new ZeroBuffer(30000000);
  165. gstrbuffer = new char[30000000];
  166. gstrout = new char[10000000];
  167. gnwidth = width;
  168. gnheight = height;
  169. gpaout = iv::modulecomm::RegisterSend(strframename.data(),1000000,1);
  170. std::thread * pthreadcap = new std::thread(threadcap,dev,name,width,height,bRotate);
  171. void * pthreadout = new std::thread(threadout);
  172. (void )pthreadcap;
  173. (void)pthreadout;
  174. StartNVENC(gstrwidth,gstrheight);
  175. return a.exec();
  176. }