EgoWindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. #include "api.h"
  2. #include "./include/EgoInterface.h"
  3. #include "../common/peer_connection.h"
  4. #include "EgoClient.h"
  5. #include "EgoWindow.h"
  6. #include "../common/iobuffer.h"
  7. #include "libyuv/convert_argb.h"
  8. #include "libyuv/planar_functions.h"
  9. #include "./include/EgoInterface.h"
  10. #include "out_sim.h"
  11. #include <time.h>
  12. #include <assert.h>
  13. #include "Protocol.pb.h"
  14. #define PI 3.141526f
  15. CEgoWindow::CEgoWindow(CEgoClient* c,IRender * render,RenderPosition pos ) :_render(render),_pos(pos), _client(c)
  16. {
  17. //_channelcreated = false;
  18. _control = ControlState::Check;
  19. }
  20. void CEgoWindow::Start()
  21. {
  22. start_ = false;
  23. //assert(n != nullptr);
  24. CMessageQueue::Start();
  25. }
  26. void CEgoWindow::Stop()
  27. {
  28. CMessageQueue::Stop();
  29. }
  30. void CEgoWindow::PostMessage(int32_t type, int64_t l /* = 0 */, int64_t r /* = 0 */)
  31. {
  32. CIOBuffer* pBuffer = CIOBuffer::Alloc(__FILE__, __LINE__);
  33. Message* message = reinterpret_cast<Message*>(pBuffer->Buffer);
  34. message->cmd = type;
  35. message->param_l = l;
  36. message->param_r = r;
  37. EnQueue(pBuffer);
  38. }
  39. void CEgoWindow::SetPeerNotify()
  40. {
  41. }
  42. void CEgoWindow::OnNotifyRep(int32_t peer)
  43. {
  44. int32_t width = 1280;
  45. int32_t height = 720;
  46. ChannelType channel = (ChannelType)(_pos - RenderPosition::FRONT);
  47. _peerconnection = std::make_unique<CPeerConnection>(channel, _client->GetSocketClient());
  48. SetRenderWindow(width, height);
  49. InitPeerConnection(peer);
  50. _peerconnection->CreateOffer();
  51. }
  52. int32_t CEgoWindow::GetSteerAngle()
  53. {
  54. return _client->GetSteerAngle();
  55. }
  56. void CEgoWindow::SetRenderWindow(int32_t width, int32_t height)
  57. {
  58. ZeroMemory(&bmi_, sizeof(bmi_));
  59. bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  60. bmi_.bmiHeader.biPlanes = 1;
  61. bmi_.bmiHeader.biBitCount = 32;
  62. bmi_.bmiHeader.biCompression = BI_RGB;
  63. /*if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
  64. {
  65. bmi_.bmiHeader.biWidth = height;
  66. bmi_.bmiHeader.biHeight = -width;
  67. }
  68. else {
  69. bmi_.bmiHeader.biWidth = width;
  70. bmi_.bmiHeader.biHeight = -height;
  71. }
  72. */
  73. bmi_.bmiHeader.biSizeImage =
  74. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  75. //为图像数据分配内存大小为biSizeImage 空间,并将其指针存储在 image_ 中
  76. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  77. // if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
  78. // _rotate.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  79. }
  80. void CEgoWindow::InitPeerConnection(int32_t peer)
  81. {
  82. //初始化 _peerconnection 对象,并传递 peer 和 _pos 参数
  83. _peerconnection->Initialize(peer, _pos);
  84. //添加数据通道,设置第一个参数为 true,第二个参数为 false
  85. _peerconnection->AddDataChannel(true, false);
  86. /*
  87. 将 CEgoWindow 类的成员函数FrameCallback 注册为回调函数,在远程视频帧数据准备就绪时调用指定的函数
  88. 注册回调函数是将FrameCallback设置为AddRemoteArgb32VideoFrameReady触发时调用的函数
  89. */
  90. _peerconnection->AddRemoteArgb32VideoFrameReady(&CEgoWindow::FrameCallback, this);
  91. //如果 _pos 的值等于 RenderPosition::FRONT,添加本地音频轨道
  92. if (_pos == RenderPosition::FRONT)
  93. {
  94. _peerconnection->AddLocalAudioTrack();
  95. }
  96. //StartRender(true);
  97. }
  98. void CEgoWindow::FrameCallback(void* user_data, const uint8_t* yptr, int32_t strideY, const uint8_t* uptr, int32_t strideU, const uint8_t* vptr, int32_t strideV, const int32_t stride, const int frame_width, const int frame_height)
  99. {
  100. auto ptr = static_cast<CEgoWindow*>(user_data);
  101. ptr->OnArgb32FrameReady(yptr, strideY, uptr, strideU, vptr, strideV, stride, frame_width, frame_height);
  102. }
  103. void CEgoWindow::SetReady(bool b)
  104. {
  105. start_ = b;
  106. if (b == false)
  107. {
  108. _render->Empty();
  109. }
  110. }
  111. void CEgoWindow::OnArgb32FrameReady(const uint8_t* yptr, int32_t strideY, const uint8_t* uptr, int32_t strideU, const uint8_t* vptr, int32_t strideV, const int32_t stride, const int width, const int height)
  112. {
  113. {
  114. // int32_t*pixels = (int32_t*)data;
  115. //std::lock_guard < std::mutex> l(buffer_lock_);
  116. if (!start_) return;
  117. if (_pos == RenderPosition::LEFT || _pos == RenderPosition::RIGHT)//|| _pos==RenderPosition::LANCHOR||_pos==RenderPosition::RANCHOR)
  118. {
  119. SetSize(width, height);
  120. int Dst_Stride_Y_mirror = width;
  121. int Dst_Stride_U_mirror = (width+1) >> 1;
  122. int Dst_Stride_V_mirror = Dst_Stride_U_mirror;
  123. // uint8_t* Dst_data=(uint8_t *)malloc(width * height * 3 / 2);
  124. int I420_Y_Size = width * height;
  125. // int I420_U_Size = (src_width >> 1) * (src_height >> 1);
  126. int I420_U_Size = width * height / 4;
  127. unsigned char* Y_data_Dst_rotate = _rotate.get();
  128. unsigned char* U_data_Dst_rotate = _rotate.get() + I420_Y_Size;
  129. unsigned char* V_data_Dst_rotate = _rotate.get() + I420_Y_Size + I420_U_Size;
  130. //libyuv::I420Mirror(yptr, strideY, uptr, strideU, vptr, strideV, Y_data_Dst_rotate, Dst_Stride_Y_mirror, U_data_Dst_rotate, Dst_Stride_U_mirror, V_data_Dst_rotate, Dst_Stride_V_mirror, width, height);
  131. //libyuv::I420ToARGB(Y_data_Dst_rotate, strideY, U_data_Dst_rotate, strideU, V_data_Dst_rotate, strideV, image_.get(), stride, width, height);
  132. //调用libyuv库的 I420ToARGB 函数,将YUV格式的I420格式数据转换为ARGB格式,并将结果存储到 image_ 中
  133. libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
  134. //free(Dst_data);
  135. }
  136. else
  137. {
  138. SetSize(width, height);
  139. libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
  140. }
  141. }
  142. _render->OnRender(image_,width,height);
  143. }
  144. void CEgoWindow::SetSize(int32_t width, int32_t height)
  145. {
  146. if (width == bmi_.bmiHeader.biWidth && height == -bmi_.bmiHeader.biHeight) {
  147. return;
  148. }
  149. // if (m_Pos == CameraPosition::CAR_LEFT || m_Pos == CameraPosition::CAR_RIGHT)
  150. // {
  151. // bmi_.bmiHeader.biWidth = height;
  152. // bmi_.bmiHeader.biHeight = -width;
  153. // }
  154. // else
  155. {
  156. bmi_.bmiHeader.biWidth = width;
  157. bmi_.bmiHeader.biHeight = -height;
  158. }
  159. bmi_.bmiHeader.biSizeImage =
  160. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  161. //通过 reset 函数重新分配了内存,为 image_ 分配大小为 biSizeImage字节的内存空间
  162. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  163. _rotate.reset(new uint8_t[width * height*3/2]);
  164. }
  165. // void CEgoWindow::WriteCanMessage(std::unordered_map<int32_t, cannet_frame>& node, bool)
  166. // {
  167. // if (_channelcreated == false || node.empty()) return;
  168. // RemoNet::CCCanMesage Req;
  169. // Req.set_islidar(false);
  170. // for (auto& it : node)
  171. // {
  172. // // if (it.second.canid == htonl(0x486))
  173. // {
  174. // auto m = Req.add_message();
  175. // m->set_head(it.second.dlc);
  176. // m->set_canid(it.second.canid);
  177. // m->set_data(it.second.data, 8);
  178. // // m->set_islidar(false);
  179. // }
  180. // // it->second.canid
  181. // }
  182. // MessageHead Head;
  183. // CIOBuffer pBuffer;
  184. // Head.Command = RemoNet::CC_CAN;
  185. // Head.Length = Req.ByteSizeLong();
  186. // Head.Serialize(pBuffer.Buffer);
  187. // auto ptr = pBuffer.Buffer + MessageHead::Size();
  188. // Req.SerializeToArray(ptr, Head.Length);
  189. // pBuffer.Length = MessageHead::Size() + Head.Length;
  190. // _peerconnection->SendData(&pBuffer);
  191. // }
  192. void CEgoWindow::Process(CIOBuffer* pBuffer)
  193. {
  194. Message* message = reinterpret_cast<Message*>(pBuffer->Buffer);
  195. switch (message->cmd)
  196. {
  197. case WM_NOTIFY_REP:
  198. OnNotifyRep((int32_t)message->param_l);
  199. break;;
  200. case WM_NOTIFY_ANSWER:
  201. OnNotifyAnswer((CIOBuffer*)message->param_l);
  202. break;
  203. /*case WM_NOTIFY_LEAVE:
  204. OnNotifyLeave();
  205. break;
  206. */
  207. case WM_NOTIFY_CANDIDATE:
  208. OnNotifyCandidate((CIOBuffer*)message->param_l);
  209. break;
  210. case WM_NOTIFY_OFFER:
  211. OnNotifyOffer((CIOBuffer*)message->param_l);
  212. break;
  213. case WM_ASK_CHANNEL:
  214. OnAskDataChannel();
  215. break;
  216. case WM_ASK_PING:
  217. OnAskPing();
  218. break;
  219. case WM_ASK_VIDEOREQ:
  220. OnAskVideoReq();
  221. break;
  222. }
  223. }
  224. void CEgoWindow::OnNotifyAnswer(CIOBuffer* pBuffer)
  225. {
  226. AnswerDesc* desc = (AnswerDesc*)pBuffer->Buffer;
  227. const char* type = desc->type;
  228. const char* sdp = desc->sdp;
  229. _peerconnection->SetRemoteDescription(type, sdp);
  230. pBuffer->Release(__FILE__, __LINE__);
  231. PostMessage(WM_ASK_CHANNEL);
  232. // DelayDataChannel();
  233. }
  234. void CEgoWindow::OnNotifyOffer(CIOBuffer* pBuffer)
  235. {
  236. OfferDesc* desc = (OfferDesc*)pBuffer->Buffer;
  237. auto type = desc->type;
  238. auto sdp = desc->sdp;
  239. _peerconnection->SetRemoteDescription(type, sdp);
  240. _peerconnection->CreateAnswer();
  241. pBuffer->Release(__FILE__, __LINE__);
  242. }
  243. void CEgoWindow::OnNotifyCandidate(CIOBuffer* pBuffer)
  244. {
  245. CandidateDesc* desc = (CandidateDesc*)pBuffer->Buffer;
  246. auto candidate = desc->candidate;
  247. auto sdp_mid = desc->sdp_mid;
  248. auto sdp_mline_index = desc->sdp_mline_index;
  249. _peerconnection->AddIceCandidate(candidate, sdp_mline_index, sdp_mid);
  250. pBuffer->Release(__FILE__, __LINE__);
  251. }
  252. void CEgoWindow::OnNotifyLeave()
  253. {
  254. if (start_) return;
  255. assert(start_ == false);
  256. StopPing();
  257. // _channelcreated = false;
  258. _peer = -1;
  259. /*if (_pos == RenderPosition::FRONT)
  260. {
  261. _peerconnection->RemoveLocalAudioTrack();
  262. }
  263. */
  264. if (_peerconnection != nullptr)
  265. {
  266. _peerconnection->Close();
  267. _peerconnection.reset();
  268. _peerconnection = nullptr;
  269. }
  270. //ddd
  271. //image_ = nullptr;
  272. if (_render != nullptr)
  273. //_render->OnRender(image_,0,0);
  274. _render->Empty();
  275. _control = ControlState::Check;
  276. }
  277. /*
  278. void CEgoWindow::DelayDataChannel()
  279. {
  280. _delayThread = std::thread(&CEgoWindow::AskDataChannel, this);
  281. _delayThread.detach();
  282. }
  283. void CEgoWindow::DelayStartPing()
  284. {
  285. _delayThread = std::thread(&CEgoWindow::StartPing, this);
  286. _delayThread.detach();
  287. }
  288. */
  289. void CEgoWindow::OnIdle()
  290. {
  291. //发送ping给下位机
  292. if (!_ping) return;
  293. if (_pos==RenderPosition::FRONT)
  294. {
  295. int64_t tick=GetTickCount64();
  296. RemoNet::CCPing Req;
  297. Req.set_tick(tick);
  298. CIOBuffer Buffer;
  299. MessageHead Head;
  300. Head.Command = RemoNet::CC_Ping;
  301. Head.Length = Req.ByteSizeLong();
  302. Head.Serialize(Buffer.Buffer);
  303. auto ptr = Buffer.Buffer + MessageHead::Size();
  304. Req.SerializeToArray(ptr, Head.Length);
  305. Buffer.Length = Head.Length + MessageHead::Size();
  306. //此处增加ping保护
  307. if(_peerconnection!= nullptr&&_peerconnection->bReadyChannel)
  308. _peerconnection->SendData(Buffer);
  309. }
  310. }
  311. void CEgoWindow::OnAskPing()
  312. {
  313. Sleep(300);
  314. _control = ControlState::Process;
  315. _ping = true;
  316. }
  317. void CEgoWindow::StopPing()
  318. {
  319. _ping = false;
  320. }
  321. void CEgoWindow::SetControlState(ControlState state)
  322. {
  323. _control = state;
  324. }
  325. void CEgoWindow::OnAskDataChannel()
  326. {
  327. Sleep(100);
  328. if (_peerconnection == nullptr) return;
  329. _peerconnection->SetDataReady();
  330. RemoNet::CCAskDataChannel Req;
  331. CIOBuffer Buffer;
  332. MessageHead Head;
  333. Head.Command = RemoNet::CC_ASKDATACHANNEL;
  334. Head.Length = Req.ByteSizeLong();
  335. Head.Serialize(Buffer.Buffer);
  336. auto ptr = Buffer.Buffer + MessageHead::Size();
  337. Req.SerializeToArray(ptr, Head.Length);
  338. Buffer.Length = Head.Length + MessageHead::Size();
  339. //_peerconnection->SendData(Buffer);
  340. //此处增加ping保护
  341. if (_peerconnection != nullptr && _peerconnection->bReadyChannel)
  342. _peerconnection->SendData(Buffer);
  343. }
  344. /*
  345. void CEgoWindow::DelayNextVideoReq()
  346. {
  347. _delayThread = std::thread(&CEgoWindow::AskVideoReq, this);
  348. _delayThread.detach();
  349. }
  350. */
  351. //请求视频数据
  352. void CEgoWindow::OnAskVideoReq()
  353. {
  354. Sleep(200);
  355. _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
  356. }
  357. /*
  358. void CEgoWindow::CreateVideoReq()
  359. {
  360. _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
  361. }
  362. */
  363. void CEgoWindow::SetPeer(int32_t peer)
  364. {
  365. _peer = peer;
  366. }
  367. void CEgoWindow::SendData(CIOBuffer& pBuffer)
  368. {
  369. if(_peerconnection!=nullptr)
  370. _peerconnection->SendData(pBuffer);
  371. }
  372. CEgoClient* CEgoWindow::GetEgoClient()
  373. {
  374. return _client;
  375. }
  376. ControlState CEgoWindow::GetControlState()
  377. {
  378. return _control;;
  379. }