main.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #include <QCoreApplication>
  2. #include <QFile>
  3. extern "C"
  4. {
  5. #include <libavcodec/avcodec.h>
  6. #include <libavutil/opt.h>
  7. #include <libavutil/imgutils.h>
  8. #include <libavutil/common.h>
  9. #include "libavutil/error.h"
  10. #include "libavutil/hwcontext.h"
  11. #include "libavformat/avformat.h"
  12. #include "libavformat/avio.h"
  13. #ifdef USE_QSV
  14. //#include "libavutil/hwcontext_qsv.h"
  15. //#include "libavutil/hwcontext_vaapi.h"
  16. #endif
  17. }
  18. #include <iostream>
  19. #include "ffmpeg_outputer.h"
  20. #include "modulecomm.h"
  21. #include "xmlparam.h"
  22. #include "rtspclientup.h"
  23. rtspclientup * gupfront = NULL;
  24. rtspclientup * guprear = NULL;
  25. rtspclientup * gupleft = NULL;
  26. rtspclientup * gupright = NULL;
  27. std::shared_ptr<char> gpstr_data;
  28. bool gbUpdate = false;
  29. int gndatasize;
  30. std::mutex gmutex;
  31. void Listenframe(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  32. {
  33. if(nSize<10)return;
  34. std::shared_ptr<char> pstr = std::shared_ptr<char>(new char[nSize]);
  35. memcpy(pstr.get(),strdata,nSize);
  36. gmutex.lock();
  37. gpstr_data = pstr;
  38. gndatasize = nSize;
  39. gbUpdate = true;
  40. gmutex.unlock();
  41. // qDebug(" %02x %02x %02x %02x %02x %02x",strdata[0],strdata[1],strdata[2],strdata[3],strdata[4],strdata[5]);
  42. iv::framedata xframe;
  43. xframe.mframe_ptr = std::shared_ptr<char>(new char[nSize]);
  44. mempcpy(xframe.mframe_ptr.get(),strdata,nSize);
  45. xframe.mndatasize = nSize;
  46. if(gupfront != NULL)
  47. {
  48. gupfront->AddData(xframe);
  49. }
  50. }
  51. void Listenfront(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  52. {
  53. if(nSize<6)return;
  54. iv::framedata xframe;
  55. xframe.mframe_ptr = std::shared_ptr<char>(new char[nSize]);
  56. mempcpy(xframe.mframe_ptr.get(),strdata,nSize);
  57. xframe.mndatasize = nSize;
  58. if(gupfront != NULL)
  59. {
  60. gupfront->AddData(xframe);
  61. }
  62. }
  63. void Listenrear(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  64. {
  65. if(nSize<6)return;
  66. iv::framedata xframe;
  67. xframe.mframe_ptr = std::shared_ptr<char>(new char[nSize]);
  68. mempcpy(xframe.mframe_ptr.get(),strdata,nSize);
  69. xframe.mndatasize = nSize;
  70. if(guprear != NULL)
  71. {
  72. guprear->AddData(xframe);
  73. }
  74. }
  75. void Listenleft(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  76. {
  77. if(nSize<6)return;
  78. iv::framedata xframe;
  79. xframe.mframe_ptr = std::shared_ptr<char>(new char[nSize]);
  80. mempcpy(xframe.mframe_ptr.get(),strdata,nSize);
  81. xframe.mndatasize = nSize;
  82. if(gupleft != NULL)
  83. {
  84. gupleft->AddData(xframe);
  85. }
  86. }
  87. void Listenright(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  88. {
  89. if(nSize<6)return;
  90. iv::framedata xframe;
  91. xframe.mframe_ptr = std::shared_ptr<char>(new char[nSize]);
  92. mempcpy(xframe.mframe_ptr.get(),strdata,nSize);
  93. xframe.mndatasize = nSize;
  94. if(gupright != NULL)
  95. {
  96. gupright->AddData(xframe);
  97. }
  98. }
  99. std::mutex gmutexlat;
  100. namespace iv {
  101. struct datapac
  102. {
  103. int64_t sendtime;
  104. int nsize;
  105. };
  106. }
  107. std::vector<iv::datapac> gvectorsend;
  108. void threadrecv()
  109. {
  110. // return;
  111. static AVFormatContext *i_fmt_ctx;
  112. int i;
  113. static bool bStop = false;
  114. std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  115. /* should set to NULL so that avformat_open_input() allocate a new one */
  116. i_fmt_ctx = NULL;
  117. //这是我用ONVIF协议得到的摄像头RTSP流媒体地址
  118. char rtspUrl[] = "rtsp://111.33.136.149:9554/testlatency";
  119. AVDictionary *avdic=NULL;
  120. char option_key[]="rtsp_transport";
  121. char option_value[]="tcp";
  122. av_dict_set(&avdic,option_key,option_value,0);
  123. if (avformat_open_input(&i_fmt_ctx, rtspUrl, NULL, &avdic)!=0)
  124. {
  125. fprintf(stderr, " = could not open input file\n");
  126. return ;
  127. }
  128. AVDictionary *opts = NULL;
  129. av_dict_set(&opts, "rtsp_transport", "tcp", 0);
  130. // av_dict_set(&opts, "muxdelay", "0.1", 0);
  131. if (avformat_find_stream_info(i_fmt_ctx,NULL)<0)
  132. {
  133. fprintf(stderr, " = could not find stream info\n");
  134. return ;
  135. }
  136. while(!bStop)
  137. {
  138. //printf("------------------------------------------------------\n");
  139. AVPacket i_pkt;
  140. av_init_packet(&i_pkt);
  141. i_pkt.size = 0;
  142. i_pkt.data = NULL;
  143. if (av_read_frame(i_fmt_ctx, &i_pkt) <0 )
  144. break;
  145. gmutexlat.lock();
  146. for(i=gvectorsend.size();i>=0;i--)
  147. {
  148. iv::datapac xpac = gvectorsend[i];
  149. if(xpac.nsize == i_pkt.size)
  150. {
  151. std::cout<<"Latency: "<<(std::chrono::system_clock::now().time_since_epoch().count()/1000000 - xpac.sendtime)<<std::endl;
  152. }
  153. }
  154. gmutexlat.unlock();
  155. std::cout<<" time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<" read packet size:"<<i_pkt.size<<std::endl;
  156. av_packet_unref(&i_pkt);
  157. }
  158. }
  159. int main(int argc, char *argv[])
  160. {
  161. QCoreApplication a(argc, argv);
  162. std::string strxmlpath;
  163. if(argc == 1)
  164. {
  165. strxmlpath = "./driver_h264_rtspclient.xml";
  166. }
  167. else
  168. {
  169. strxmlpath = argv[1];
  170. }
  171. iv::xmlparam::Xmlparam xp(strxmlpath);
  172. std::string strfrontmsgname = xp.GetParam("frontmsg","h264front");
  173. std::string strrearmsgname = xp.GetParam("rearmsg","h264rear");
  174. std::string strleftmsgname = xp.GetParam("leftmsg","h264left");
  175. std::string strrightmsgname = xp.GetParam("rightmsg","h264right");
  176. std::string strvin = xp.GetParam("VIN","AAAAAAAAAAAAAAVTD");
  177. std::string strpass = xp.GetParam("pass","hello");
  178. int nwidth = xp.GetParam("width",1920);
  179. int nheigth = xp.GetParam("height",1080);
  180. std::string strserverip = xp.GetParam("ServerIP","111.33.136.149");
  181. std::string strserverport = xp.GetParam("ServerPort","9554");
  182. std::string strfrontrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
  183. +strvin + "-front-" + strpass;
  184. std::string strrearrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
  185. +strvin + "-rear-" + strpass;
  186. std::string strleftrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
  187. +strvin + "-left-" + strpass;
  188. std::string strrightrtsp = "rtsp://" + strserverip+":"+strserverport+"/"
  189. +strvin + "-right-" + strpass;
  190. av_register_all(); //初始化FFMPEG 调用了这个才能正常适用编码器和解码器
  191. //Network
  192. avformat_network_init();
  193. #ifndef TESTLATENCY
  194. rtspclientup * pup = new rtspclientup(strfrontrtsp.data(),nwidth,nheigth);
  195. gupfront = pup;
  196. void * pafront = iv::modulecomm::RegisterRecv(strfrontmsgname.data(),Listenfront);
  197. (void)pafront;
  198. if(strrearmsgname != "nomessage")
  199. {
  200. guprear = new rtspclientup(strrearrtsp.data(),nwidth,nheigth);
  201. void * parear = iv::modulecomm::RegisterRecv(strrearmsgname.data(),Listenrear);
  202. (void)parear;
  203. }
  204. if(strrearmsgname != "nomessage")
  205. {
  206. gupleft = new rtspclientup(strleftrtsp.data(),nwidth,nheigth);
  207. void * paleft = iv::modulecomm::RegisterRecv(strleftmsgname.data(),Listenleft);
  208. (void)paleft;
  209. }
  210. if(strrearmsgname != "nomessage")
  211. {
  212. gupright = new rtspclientup(strrightrtsp.data(),nwidth,nheigth);
  213. void * paright = iv::modulecomm::RegisterRecv(strrightmsgname.data(),Listenright);
  214. (void)paright;
  215. }
  216. return a.exec();
  217. #endif
  218. void * pa = iv::modulecomm::RegisterRecv("h264front",Listenframe);
  219. (void)pa;
  220. AVFormatContext *ifmt_ctx = NULL;
  221. AVPacket pkt;
  222. const char *in_filename, *out_filename;
  223. FfmpegOutputer *pusher = NULL;
  224. int ret;
  225. int frame_index = 0;
  226. in_filename = "./imx291.h264";
  227. out_filename = "rtsp://111.33.136.149:9554/testhello2";
  228. std::thread * precvthread = new std::thread(threadrecv);
  229. (void)precvthread;
  230. if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
  231. printf("Could not open input file.");
  232. return -1;
  233. }
  234. if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
  235. printf("Failed to retrieve input stream information");
  236. return -2 ;
  237. }
  238. ifmt_ctx->streams[0]->codecpar->width = 1920;
  239. ifmt_ctx->streams[0]->codecpar->height = 1080;
  240. AVFormatContext * fmtctx = NULL;
  241. out_filename = "rtsp://111.33.136.149:9554/testlatency";
  242. int nrtn = avformat_alloc_output_context2(&fmtctx,NULL,"rtsp","rtsp://111.33.136.149:9554/testlatency");
  243. (void)nrtn;
  244. fmtctx->bit_rate = 2000000;
  245. fmtctx->fps_probe_size = 30;
  246. AVStream *out_stream = avformat_new_stream(fmtctx, NULL);
  247. QFile xFile;
  248. #ifdef SAVECODEPAR
  249. xFile.setFileName("./codepar");
  250. if(xFile.open(QIODevice::ReadWrite))
  251. {
  252. xFile.write((char*)ifmt_ctx->streams[0]->codecpar,sizeof(AVCodecParameters));
  253. if(ifmt_ctx->streams[0]->codecpar->extradata_size>0)
  254. {
  255. xFile.write((char*)ifmt_ctx->streams[0]->codecpar->extradata,ifmt_ctx->streams[0]->codecpar->extradata_size);
  256. }
  257. xFile.close();
  258. return 0;
  259. }
  260. #endif
  261. xFile.setFileName(":/codepar");
  262. if(xFile.open(QIODevice::ReadOnly))
  263. {
  264. xFile.read((char *)out_stream->codecpar,sizeof(AVCodecParameters));
  265. if(out_stream->codecpar->extradata_size>0)
  266. {
  267. out_stream->codecpar->extradata = new uint8_t[out_stream->codecpar->extradata_size];
  268. xFile.read((char*)out_stream->codecpar->extradata,out_stream->codecpar->extradata_size);
  269. }
  270. xFile.close();
  271. }
  272. else
  273. {
  274. std::cout<<"can't get codepar from file."<<std::endl;
  275. return -1;
  276. }
  277. out_stream->codecpar->bit_rate = 2000000;
  278. out_stream->codecpar->width = 1280;
  279. out_stream->codecpar->height = 720;
  280. if (NULL == pusher) {
  281. pusher = new FfmpegOutputer();
  282. // ret = pusher->OpenOutputStream(out_filename, ifmt_ctx);
  283. ret = pusher->OpenOutputStream(out_filename, fmtctx);
  284. if (ret != 0){
  285. return -3;
  286. }
  287. }
  288. av_dump_format(ifmt_ctx, 0, in_filename, 0);
  289. int pos = 0;
  290. // av_read_frame(ifmt_ctx, &pkt);
  291. // pkt = av_packet_alloc();
  292. while (true) {
  293. if(gbUpdate == false)
  294. {
  295. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  296. // av_usleep(1000);
  297. // std::cout<<"sleep. "<<std::endl;
  298. continue;
  299. }
  300. // continue;
  301. gmutex.lock();
  302. pkt.buf = NULL;
  303. pkt.duration = 0;
  304. pkt.data = new unsigned char[gndatasize];
  305. // pkt.buf->data = pkt.data;
  306. memcpy(pkt.data, gpstr_data.get(),gndatasize);
  307. pkt.size = gndatasize;
  308. pkt.stream_index = 0;
  309. pkt.side_data = 0;
  310. pkt.side_data_elems = 0;
  311. // std::cout<<" size : "<<gndatasize<<std::endl;
  312. // std::cout<<" buf size: "<<pkt.buf->size<<std::endl;
  313. // pkt.buf->size = gndatasize;
  314. pkt.pos = pos;
  315. pkt.pts = AV_NOPTS_VALUE;
  316. pkt.dts = AV_NOPTS_VALUE;
  317. pos = pos + gndatasize;
  318. gbUpdate = false;
  319. gmutex.unlock();
  320. pkt.flags = 0;
  321. iv::datapac xpac;
  322. xpac.nsize = pkt.size;
  323. xpac.sendtime = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
  324. // std::cout<<"send frame "<<std::endl;
  325. // ret = av_read_frame(ifmt_ctx, &pkt);
  326. gmutexlat.lock();
  327. gvectorsend.push_back(xpac);
  328. while(gvectorsend.size()>100)gvectorsend.erase(gvectorsend.begin());
  329. gmutexlat.unlock();
  330. std::cout<<" time: "<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<" pos: "<<pkt.pos<<" size: "<<pkt.size<<" flats: "<<pkt.flags<< std::endl;
  331. // if (ret < 0) break;
  332. pkt.duration = 3*1000;
  333. // std::cout<<" pts: "<<pkt.pts<<" dts: "<<pkt.dts<<std::endl;
  334. if (pkt.pts == AV_NOPTS_VALUE) {
  335. pkt.dts = pkt.pts = 1000* (1.0/30)*90*frame_index;
  336. // pkt.dts = pkt.pts = frame_index * 1;
  337. // frame_index++;
  338. }
  339. // std::cout<<" pts: "<<pkt.pts<<" dts: "<<pkt.dts<<std::endl;
  340. pusher->InputPacket(&pkt);
  341. delete pkt.data;
  342. av_packet_unref(&pkt);
  343. frame_index++;
  344. // av_usleep(40000);
  345. }
  346. end:
  347. avformat_close_input(&ifmt_ctx);
  348. avformat_free_context(ifmt_ctx);
  349. delete pusher;
  350. return a.exec();
  351. }