EgoWindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. #include "api/video/video_frame.h"
  2. #include "api.h"
  3. #include "./include/EgoInterface.h"
  4. #include "../common/peer_connection.h"
  5. #include "EgoClient.h"
  6. #include "EgoWindow.h"
  7. #include "../common/iobuffer.h"
  8. #include "libyuv/convert_argb.h"
  9. #include "libyuv/planar_functions.h"
  10. #include "./include/EgoInterface.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. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  76. // if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
  77. // _rotate.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  78. }
  79. void CEgoWindow::InitPeerConnection(int32_t peer)
  80. {
  81. _peerconnection->Initialize(peer, _pos);
  82. _peerconnection->AddDataChannel(true, false);
  83. _peerconnection->AddRemoteVideoFrameReady(&CEgoWindow::RemoteFrameCallback, this);
  84. if (_pos == RenderPosition::FRONT)
  85. {
  86. _peerconnection->AddLocalAudioTrack();
  87. }
  88. //StartRender(true);
  89. }
  90. void CEgoWindow::RemoteFrameCallback(void* user_data, const webrtc::VideoFrame& frame)
  91. {
  92. auto ptr = static_cast<CEgoWindow*>(user_data);
  93. ptr->OverlayVideo(frame);
  94. rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
  95. frame.video_frame_buffer());
  96. const int width = frame.width();
  97. const int height = frame.height();
  98. if (buffer->type() != webrtc::VideoFrameBuffer::Type::kI420A) {
  99. rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer =
  100. buffer->ToI420();
  101. const uint8_t* yptr = i420_buffer->DataY();
  102. const uint8_t* uptr = i420_buffer->DataU();
  103. const uint8_t* vptr = i420_buffer->DataV();
  104. const uint8_t* aptr = nullptr;
  105. ptr->OnArgb32FrameReady(yptr, i420_buffer->StrideY(), uptr, i420_buffer->StrideU(), vptr, i420_buffer->StrideV(), width * 4, width, height);
  106. }
  107. else {
  108. const webrtc::I420ABufferInterface* i420a_buffer = buffer->GetI420A();
  109. const uint8_t* yptr = i420a_buffer->DataY();
  110. const uint8_t* uptr = i420a_buffer->DataU();
  111. const uint8_t* vptr = i420a_buffer->DataV();
  112. const uint8_t* aptr = i420a_buffer->DataA();
  113. ptr->OnArgb32FrameReady(yptr, i420a_buffer->StrideY(), uptr, i420a_buffer->StrideU(), vptr, i420a_buffer->StrideV(), width * 4, width, height);
  114. }
  115. }
  116. void CEgoWindow::SetReady(bool b)
  117. {
  118. start_ = b;
  119. if (b == false)
  120. {
  121. _render->Empty();
  122. }
  123. }
  124. 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)
  125. {
  126. {
  127. // int32_t*pixels = (int32_t*)data;
  128. //std::lock_guard < std::mutex> l(buffer_lock_);
  129. if (!start_) return;
  130. if (_pos == RenderPosition::LEFT || _pos == RenderPosition::RIGHT)//|| _pos==RenderPosition::LANCHOR||_pos==RenderPosition::RANCHOR)
  131. {
  132. SetSize(width, height);
  133. int Dst_Stride_Y_mirror = width;
  134. int Dst_Stride_U_mirror = (width+1) >> 1;
  135. int Dst_Stride_V_mirror = Dst_Stride_U_mirror;
  136. // uint8_t* Dst_data=(uint8_t *)malloc(width * height * 3 / 2);
  137. int I420_Y_Size = width * height;
  138. // int I420_U_Size = (src_width >> 1) * (src_height >> 1);
  139. int I420_U_Size = width * height / 4;
  140. unsigned char* Y_data_Dst_rotate = _rotate.get();
  141. unsigned char* U_data_Dst_rotate = _rotate.get() + I420_Y_Size;
  142. unsigned char* V_data_Dst_rotate = _rotate.get() + I420_Y_Size + I420_U_Size;
  143. //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);
  144. //libyuv::I420ToARGB(Y_data_Dst_rotate, strideY, U_data_Dst_rotate, strideU, V_data_Dst_rotate, strideV, image_.get(), stride, width, height);
  145. libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
  146. //free(Dst_data);
  147. }
  148. else
  149. {
  150. SetSize(width, height);
  151. libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
  152. }
  153. }
  154. _render->OnRender(image_,width,height);
  155. }
  156. void CEgoWindow::SetSize(int32_t width, int32_t height)
  157. {
  158. if (width == bmi_.bmiHeader.biWidth && height == -bmi_.bmiHeader.biHeight) {
  159. return;
  160. }
  161. // if (m_Pos == CameraPosition::CAR_LEFT || m_Pos == CameraPosition::CAR_RIGHT)
  162. // {
  163. // bmi_.bmiHeader.biWidth = height;
  164. // bmi_.bmiHeader.biHeight = -width;
  165. // }
  166. // else
  167. {
  168. bmi_.bmiHeader.biWidth = width;
  169. bmi_.bmiHeader.biHeight = -height;
  170. }
  171. bmi_.bmiHeader.biSizeImage =
  172. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  173. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  174. _rotate.reset(new uint8_t[width * height*3/2]);
  175. }
  176. // void CEgoWindow::WriteCanMessage(std::unordered_map<int32_t, cannet_frame>& node, bool)
  177. // {
  178. // if (_channelcreated == false || node.empty()) return;
  179. // RemoNet::CCCanMesage Req;
  180. // Req.set_islidar(false);
  181. // for (auto& it : node)
  182. // {
  183. // // if (it.second.canid == htonl(0x486))
  184. // {
  185. // auto m = Req.add_message();
  186. // m->set_head(it.second.dlc);
  187. // m->set_canid(it.second.canid);
  188. // m->set_data(it.second.data, 8);
  189. // // m->set_islidar(false);
  190. // }
  191. // // it->second.canid
  192. // }
  193. // MessageHead Head;
  194. // CIOBuffer pBuffer;
  195. // Head.Command = RemoNet::CC_CAN;
  196. // Head.Length = Req.ByteSizeLong();
  197. // Head.Serialize(pBuffer.Buffer);
  198. // auto ptr = pBuffer.Buffer + MessageHead::Size();
  199. // Req.SerializeToArray(ptr, Head.Length);
  200. // pBuffer.Length = MessageHead::Size() + Head.Length;
  201. // _peerconnection->SendData(&pBuffer);
  202. // }
  203. void CEgoWindow::Process(CIOBuffer* pBuffer)
  204. {
  205. Message* message = reinterpret_cast<Message*>(pBuffer->Buffer);
  206. switch (message->cmd)
  207. {
  208. case WM_NOTIFY_REP:
  209. OnNotifyRep((int32_t)message->param_l);
  210. break;;
  211. case WM_NOTIFY_ANSWER:
  212. OnNotifyAnswer((CIOBuffer*)message->param_l);
  213. break;
  214. /*case WM_NOTIFY_LEAVE:
  215. OnNotifyLeave();
  216. break;
  217. */
  218. case WM_NOTIFY_CANDIDATE:
  219. OnNotifyCandidate((CIOBuffer*)message->param_l);
  220. break;
  221. case WM_NOTIFY_OFFER:
  222. OnNotifyOffer((CIOBuffer*)message->param_l);
  223. break;
  224. case WM_ASK_CHANNEL:
  225. OnAskDataChannel();
  226. break;
  227. case WM_ASK_PING:
  228. OnAskPing();
  229. break;
  230. case WM_ASK_VIDEOREQ:
  231. OnAskVideoReq();
  232. break;
  233. }
  234. }
  235. void CEgoWindow::OnNotifyAnswer(CIOBuffer* pBuffer)
  236. {
  237. AnswerDesc* desc = (AnswerDesc*)pBuffer->Buffer;
  238. const char* type = desc->type;
  239. const char* sdp = desc->sdp;
  240. _peerconnection->SetRemoteDescription(type, sdp);
  241. pBuffer->Release(__FILE__, __LINE__);
  242. PostMessage(WM_ASK_CHANNEL);
  243. // DelayDataChannel();
  244. }
  245. void CEgoWindow::OnNotifyOffer(CIOBuffer* pBuffer)
  246. {
  247. OfferDesc* desc = (OfferDesc*)pBuffer->Buffer;
  248. auto type = desc->type;
  249. auto sdp = desc->sdp;
  250. _peerconnection->SetRemoteDescription(type, sdp);
  251. _peerconnection->CreateAnswer();
  252. pBuffer->Release(__FILE__, __LINE__);
  253. }
  254. void CEgoWindow::OnNotifyCandidate(CIOBuffer* pBuffer)
  255. {
  256. CandidateDesc* desc = (CandidateDesc*)pBuffer->Buffer;
  257. auto candidate = desc->candidate;
  258. auto sdp_mid = desc->sdp_mid;
  259. auto sdp_mline_index = desc->sdp_mline_index;
  260. _peerconnection->AddIceCandidate(candidate, sdp_mline_index, sdp_mid);
  261. pBuffer->Release(__FILE__, __LINE__);
  262. }
  263. void CEgoWindow::OnNotifyLeave()
  264. {
  265. if (start_) return;
  266. assert(start_ == false);
  267. StopPing();
  268. // _channelcreated = false;
  269. _peer = -1;
  270. /*if (_pos == RenderPosition::FRONT)
  271. {
  272. _peerconnection->RemoveLocalAudioTrack();
  273. }
  274. */
  275. if (_peerconnection != nullptr)
  276. {
  277. _peerconnection->Close();
  278. _peerconnection.reset();
  279. _peerconnection = nullptr;
  280. }
  281. image_ = nullptr;
  282. if(_render!=nullptr)
  283. _render->OnRender(image_,0,0);
  284. _control = ControlState::Check;
  285. }
  286. /*
  287. void CEgoWindow::DelayDataChannel()
  288. {
  289. _delayThread = std::thread(&CEgoWindow::AskDataChannel, this);
  290. _delayThread.detach();
  291. }
  292. void CEgoWindow::DelayStartPing()
  293. {
  294. _delayThread = std::thread(&CEgoWindow::StartPing, this);
  295. _delayThread.detach();
  296. }
  297. */
  298. void CEgoWindow::OnIdle()
  299. {
  300. if (!_ping) return;
  301. if (_pos==RenderPosition::FRONT)
  302. {
  303. int64_t tick=GetTickCount64();
  304. RemoNet::CCPing Req;
  305. Req.set_tick(tick);
  306. CIOBuffer Buffer;
  307. MessageHead Head;
  308. Head.Command = RemoNet::CC_Ping;
  309. Head.Length = Req.ByteSizeLong();
  310. Head.Serialize(Buffer.Buffer);
  311. auto ptr = Buffer.Buffer + MessageHead::Size();
  312. Req.SerializeToArray(ptr, Head.Length);
  313. Buffer.Length = Head.Length + MessageHead::Size();
  314. _peerconnection->SendData(Buffer);
  315. }
  316. }
  317. void CEgoWindow::OnAskPing()
  318. {
  319. Sleep(300);
  320. _control = ControlState::Process;
  321. _ping = true;
  322. }
  323. void CEgoWindow::StopPing()
  324. {
  325. _ping = false;
  326. }
  327. void CEgoWindow::SetControlState(ControlState state)
  328. {
  329. _control = state;
  330. }
  331. void CEgoWindow::OnAskDataChannel()
  332. {
  333. Sleep(100);
  334. if (_peerconnection == nullptr) return;
  335. _peerconnection->SetDataReady();
  336. RemoNet::CCAskDataChannel Req;
  337. CIOBuffer Buffer;
  338. MessageHead Head;
  339. Head.Command = RemoNet::CC_ASKDATACHANNEL;
  340. Head.Length = Req.ByteSizeLong();
  341. Head.Serialize(Buffer.Buffer);
  342. auto ptr = Buffer.Buffer + MessageHead::Size();
  343. Req.SerializeToArray(ptr, Head.Length);
  344. Buffer.Length = Head.Length + MessageHead::Size();
  345. _peerconnection->SendData(Buffer);
  346. }
  347. /*
  348. void CEgoWindow::DelayNextVideoReq()
  349. {
  350. _delayThread = std::thread(&CEgoWindow::AskVideoReq, this);
  351. _delayThread.detach();
  352. }
  353. */
  354. void CEgoWindow::OnAskVideoReq()
  355. {
  356. Sleep(200);
  357. _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
  358. }
  359. /*
  360. void CEgoWindow::CreateVideoReq()
  361. {
  362. _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
  363. }
  364. */
  365. void CEgoWindow::SetPeer(int32_t peer)
  366. {
  367. _peer = peer;
  368. }
  369. void CEgoWindow::SendData(CIOBuffer& pBuffer)
  370. {
  371. if(_peerconnection!=nullptr)
  372. _peerconnection->SendData(pBuffer);
  373. }
  374. CEgoClient* CEgoWindow::GetEgoClient()
  375. {
  376. return _client;
  377. }
  378. ControlState CEgoWindow::GetControlState()
  379. {
  380. return _control;;
  381. }
  382. void CEgoWindow::OverlayVideo(const webrtc::VideoFrame& frame)
  383. {
  384. _client->OverlayVideo(_pos, frame);
  385. }