remote_window.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "pch.h"
  2. #include "api/video/video_frame.h"
  3. #include "cap_interface.h"
  4. #include "../common/comm.h"
  5. #include "../common/iobuffer.h"
  6. #include "../common/remote_def.h"
  7. #include "remote.pb.h"
  8. #include <memory>
  9. #include "peer_connection.h"
  10. #include "socket_remote.h"
  11. #include "remote_window.h"
  12. #include "message_queue.h"
  13. #include "libyuv/convert_argb.h"
  14. #include "libyuv/planar_functions.h"
  15. CRemoteWindow::CRemoteWindow(EgoType type, CMessageQueue* q, RenderPosition pos, IRender* render):_pos(pos),_message(q), _render(render),_type(type)
  16. {
  17. }
  18. void CRemoteWindow::OnNotifyRep(int32_t peer)
  19. {
  20. int32_t width = 1280;
  21. int32_t height = 720;
  22. //ChannelType channel = (ChannelType)(_pos - RenderPosition::FRONT);
  23. _peerconnection = std::make_unique<CPeerConnection>(_message->GetRemoteClient());
  24. SetRenderWindow(width, height);
  25. InitPeerConnection(peer);
  26. _peerconnection->CreateOffer();
  27. }
  28. void CRemoteWindow::OnNotifyAnswer(CIOBuffer* pBuffer)
  29. {
  30. AnswerDesc* desc = (AnswerDesc*)pBuffer->Buffer;
  31. const char* type = desc->type;
  32. const char* sdp = desc->sdp;
  33. _peerconnection->SetRemoteDescription(type, sdp);
  34. pBuffer->Release(__FILE__, __LINE__);
  35. // DelayDataChannel();
  36. }
  37. void CRemoteWindow::SetRenderWindow(int32_t width, int32_t height)
  38. {
  39. ZeroMemory(&bmi_, sizeof(bmi_));
  40. bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  41. bmi_.bmiHeader.biPlanes = 1;
  42. bmi_.bmiHeader.biBitCount = 32;
  43. bmi_.bmiHeader.biCompression = BI_RGB;
  44. /*if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
  45. {
  46. bmi_.bmiHeader.biWidth = height;
  47. bmi_.bmiHeader.biHeight = -width;
  48. }
  49. else {
  50. bmi_.bmiHeader.biWidth = width;
  51. bmi_.bmiHeader.biHeight = -height;
  52. }
  53. */
  54. bmi_.bmiHeader.biSizeImage =
  55. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  56. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  57. // if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
  58. // _rotate.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  59. }
  60. void CRemoteWindow::SetSize(int32_t width, int32_t height)
  61. {
  62. if (width == bmi_.bmiHeader.biWidth && height == -bmi_.bmiHeader.biHeight) {
  63. return;
  64. }
  65. // if (m_Pos == CameraPosition::CAR_LEFT || m_Pos == CameraPosition::CAR_RIGHT)
  66. // {
  67. // bmi_.bmiHeader.biWidth = height;
  68. // bmi_.bmiHeader.biHeight = -width;
  69. // }
  70. // else
  71. {
  72. bmi_.bmiHeader.biWidth = width;
  73. bmi_.bmiHeader.biHeight = -height;
  74. }
  75. bmi_.bmiHeader.biSizeImage =
  76. width * height * (bmi_.bmiHeader.biBitCount >> 3);
  77. image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
  78. }
  79. void CRemoteWindow::InitPeerConnection(int32_t peer)
  80. {
  81. if (_peerconnection != nullptr)
  82. {
  83. _peerconnection->Initialize(peer,_pos);
  84. // if(_local->IsAR()==false)
  85. // _peerconnection->AddLocalArgb32VideoFrameReady(&CEgoWindow::LocalFrameCallback, this);
  86. if(_type==EgoType::Monitor)
  87. _peerconnection->AddRemoteVideoFrameReady(&CRemoteWindow::RemoteFrameCallback, this);
  88. else
  89. {
  90. _video = _peerconnection->CreateOverlayVideo();
  91. _peerconnection->AddLocalVideoTrack(_video);
  92. }
  93. }
  94. _start = true;
  95. }
  96. void CRemoteWindow::OnNotifyReq(int32_t index)
  97. {
  98. assert(_type == EgoType::User);
  99. _peerconnection = std::make_unique<CPeerConnection>(_message->GetRemoteClient());
  100. _message->GetRemoteClient()->WriteVideoRep(_peer, remote::VideoDesc::OK, index);
  101. }
  102. void CRemoteWindow::OnNotifyCandidate(CIOBuffer* pBuffer)
  103. {
  104. CandidateDesc* desc = (CandidateDesc*)pBuffer->Buffer;
  105. auto candidate = desc->candidate;
  106. auto sdp_mid = desc->sdp_mid;
  107. auto sdp_mline_index = desc->sdp_mline_index;
  108. _peerconnection->AddIceCandidate(candidate, sdp_mline_index, sdp_mid);
  109. pBuffer->Release(__FILE__, __LINE__);
  110. }
  111. void CRemoteWindow::OnNotifyOffer(CIOBuffer* pBuffer)
  112. {
  113. assert(_type == EgoType::User);
  114. OfferDesc* desc = (OfferDesc*)pBuffer->Buffer;
  115. auto type = desc->type;
  116. auto sdp = desc->sdp;
  117. InitPeerConnection(_peer);
  118. _peerconnection->SetRemoteDescription(type, sdp);
  119. _peerconnection->CreateAnswer();
  120. pBuffer->Release(__FILE__, __LINE__);
  121. }
  122. void CRemoteWindow::OnAskVideoReq()
  123. {
  124. Sleep(200);
  125. _message->GetRemoteClient()->WriteVideoReq(_peer, _pos);
  126. }
  127. void CRemoteWindow::RemoteFrameCallback(void* user_data,
  128. const webrtc::VideoFrame& frame)
  129. {
  130. auto ptr = static_cast<CRemoteWindow*>(user_data);
  131. rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
  132. frame.video_frame_buffer());
  133. const int width = frame.width();
  134. const int height = frame.height();
  135. if (buffer->type() != webrtc::VideoFrameBuffer::Type::kI420A) {
  136. rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer =
  137. buffer->ToI420();
  138. const uint8_t* yptr = i420_buffer->DataY();
  139. const uint8_t* uptr = i420_buffer->DataU();
  140. const uint8_t* vptr = i420_buffer->DataV();
  141. const uint8_t* aptr = nullptr;
  142. ptr->OnArgb32FrameReady(yptr, i420_buffer->StrideY(), uptr, i420_buffer->StrideU(), vptr, i420_buffer->StrideV(), width * 4, width, height);
  143. }
  144. else {
  145. const webrtc::I420ABufferInterface* i420a_buffer = buffer->GetI420A();
  146. const uint8_t* yptr = i420a_buffer->DataY();
  147. const uint8_t* uptr = i420a_buffer->DataU();
  148. const uint8_t* vptr = i420a_buffer->DataV();
  149. const uint8_t* aptr = i420a_buffer->DataA();
  150. ptr->OnArgb32FrameReady(yptr, i420a_buffer->StrideY(), uptr, i420a_buffer->StrideU(), vptr, i420a_buffer->StrideV(), width * 4, width, height);
  151. }
  152. }
  153. void CRemoteWindow::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)
  154. {
  155. {
  156. // int32_t*pixels = (int32_t*)data;
  157. //std::lock_guard < std::mutex> l(buffer_lock_);
  158. if (!_start) return;
  159. {
  160. SetSize(width, height);
  161. libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
  162. }
  163. }
  164. _render->OnRender(image_, width, height);
  165. }
  166. void CRemoteWindow::OverlayVideo(const webrtc::VideoFrame& frame)
  167. {
  168. assert(_type == EgoType::User);
  169. if (_start&&_video != nullptr)
  170. _video->OnVideoData(frame);
  171. }
  172. void CRemoteWindow::OnNotifyLeave()
  173. {
  174. _start = false;
  175. // _channelcreated = false;
  176. _peer = -1;
  177. /*if (_pos == RenderPosition::FRONT)
  178. {
  179. _peerconnection->RemoveLocalAudioTrack();
  180. }
  181. */
  182. if (_peerconnection != nullptr)
  183. {
  184. _peerconnection->Close();
  185. _peerconnection.reset();
  186. _peerconnection = nullptr;
  187. }
  188. image_ = nullptr;
  189. if (_type==EgoType::Monitor&& _render != nullptr)
  190. _render->OnRender(image_, 0, 0);
  191. else if (_type == EgoType::User)
  192. _video = nullptr;
  193. }
  194. void CRemoteWindow::SetPeer(int32_t peer)
  195. {
  196. _peer = peer;
  197. }