EgoWindow.cpp 10 KB

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