EgoWindow.cpp 10 KB

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