123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- #include "api.h"
- #include "./include/EgoInterface.h"
- #include "../common/peer_connection.h"
- #include "EgoClient.h"
- #include "EgoWindow.h"
- #include "../common/iobuffer.h"
- #include "libyuv/convert_argb.h"
- #include "libyuv/planar_functions.h"
- #include "./include/EgoInterface.h"
- #include "out_sim.h"
- #include <time.h>
- #include <assert.h>
- #include "Protocol.pb.h"
- #define PI 3.141526f
- CEgoWindow::CEgoWindow(CEgoClient* c,IRender * render,RenderPosition pos ) :_render(render),_pos(pos), _client(c)
- {
- //_channelcreated = false;
- _control = ControlState::Check;
-
- }
- void CEgoWindow::Start()
- {
- start_ = false;
- //assert(n != nullptr);
- CMessageQueue::Start();
-
- }
- void CEgoWindow::Stop()
- {
- CMessageQueue::Stop();
-
- }
- void CEgoWindow::PostMessage(int32_t type, int64_t l /* = 0 */, int64_t r /* = 0 */)
- {
- CIOBuffer* pBuffer = CIOBuffer::Alloc(__FILE__, __LINE__);
-
- Message* message = reinterpret_cast<Message*>(pBuffer->Buffer);
- message->cmd = type;
- message->param_l = l;
- message->param_r = r;
- EnQueue(pBuffer);
- }
- void CEgoWindow::SetPeerNotify()
- {
-
- }
- void CEgoWindow::OnNotifyRep(int32_t peer)
- {
- int32_t width = 1280;
- int32_t height = 720;
- ChannelType channel = (ChannelType)(_pos - RenderPosition::FRONT);
-
- _peerconnection = std::make_unique<CPeerConnection>(channel, _client->GetSocketClient());
- SetRenderWindow(width, height);
- InitPeerConnection(peer);
- _peerconnection->CreateOffer();
- }
- int32_t CEgoWindow::GetSteerAngle()
- {
- return _client->GetSteerAngle();
- }
- void CEgoWindow::SetRenderWindow(int32_t width, int32_t height)
- {
- ZeroMemory(&bmi_, sizeof(bmi_));
- bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi_.bmiHeader.biPlanes = 1;
- bmi_.bmiHeader.biBitCount = 32;
- bmi_.bmiHeader.biCompression = BI_RGB;
- /*if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
- {
- bmi_.bmiHeader.biWidth = height;
- bmi_.bmiHeader.biHeight = -width;
- }
- else {
- bmi_.bmiHeader.biWidth = width;
- bmi_.bmiHeader.biHeight = -height;
- }
- */
- bmi_.bmiHeader.biSizeImage =
- width * height * (bmi_.bmiHeader.biBitCount >> 3);
-
- //为图像数据分配内存大小为biSizeImage 空间,并将其指针存储在 image_ 中
- image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
- // if (_pos == RenderPosition::LMIRROR || _pos == RenderPosition::RMIRROR)
- // _rotate.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
- }
- void CEgoWindow::InitPeerConnection(int32_t peer)
- {
- //初始化 _peerconnection 对象,并传递 peer 和 _pos 参数
- _peerconnection->Initialize(peer, _pos);
-
- //添加数据通道,设置第一个参数为 true,第二个参数为 false
- _peerconnection->AddDataChannel(true, false);
- /*
- 将 CEgoWindow 类的成员函数FrameCallback 注册为回调函数,在远程视频帧数据准备就绪时调用指定的函数
- 注册回调函数是将FrameCallback设置为AddRemoteArgb32VideoFrameReady触发时调用的函数
- */
- _peerconnection->AddRemoteArgb32VideoFrameReady(&CEgoWindow::FrameCallback, this);
- //如果 _pos 的值等于 RenderPosition::FRONT,添加本地音频轨道
- if (_pos == RenderPosition::FRONT)
- {
- _peerconnection->AddLocalAudioTrack();
- }
- //StartRender(true);
- }
- 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)
- {
- auto ptr = static_cast<CEgoWindow*>(user_data);
- ptr->OnArgb32FrameReady(yptr, strideY, uptr, strideU, vptr, strideV, stride, frame_width, frame_height);
- }
- void CEgoWindow::SetReady(bool b)
- {
- start_ = b;
- if (b == false)
- {
- _render->Empty();
- }
- }
- 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)
- {
- {
- // int32_t*pixels = (int32_t*)data;
- //std::lock_guard < std::mutex> l(buffer_lock_);
- if (!start_) return;
-
- if (_pos == RenderPosition::LEFT || _pos == RenderPosition::RIGHT)//|| _pos==RenderPosition::LANCHOR||_pos==RenderPosition::RANCHOR)
- {
- SetSize(width, height);
- int Dst_Stride_Y_mirror = width;
- int Dst_Stride_U_mirror = (width+1) >> 1;
- int Dst_Stride_V_mirror = Dst_Stride_U_mirror;
- // uint8_t* Dst_data=(uint8_t *)malloc(width * height * 3 / 2);
- int I420_Y_Size = width * height;
- // int I420_U_Size = (src_width >> 1) * (src_height >> 1);
- int I420_U_Size = width * height / 4;
- unsigned char* Y_data_Dst_rotate = _rotate.get();
- unsigned char* U_data_Dst_rotate = _rotate.get() + I420_Y_Size;
- unsigned char* V_data_Dst_rotate = _rotate.get() + I420_Y_Size + I420_U_Size;
- //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);
- //libyuv::I420ToARGB(Y_data_Dst_rotate, strideY, U_data_Dst_rotate, strideU, V_data_Dst_rotate, strideV, image_.get(), stride, width, height);
-
- //调用libyuv库的 I420ToARGB 函数,将YUV格式的I420格式数据转换为ARGB格式,并将结果存储到 image_ 中
- libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
- //free(Dst_data);
- }
- else
-
- {
- SetSize(width, height);
- libyuv::I420ToARGB(yptr, strideY, uptr, strideU, vptr, strideV, image_.get(), stride, width, height);
- }
-
- }
-
- _render->OnRender(image_,width,height);
- }
-
- void CEgoWindow::SetSize(int32_t width, int32_t height)
- {
- if (width == bmi_.bmiHeader.biWidth && height == -bmi_.bmiHeader.biHeight) {
- return;
- }
- // if (m_Pos == CameraPosition::CAR_LEFT || m_Pos == CameraPosition::CAR_RIGHT)
- // {
- // bmi_.bmiHeader.biWidth = height;
- // bmi_.bmiHeader.biHeight = -width;
- // }
- // else
- {
- bmi_.bmiHeader.biWidth = width;
- bmi_.bmiHeader.biHeight = -height;
- }
- bmi_.bmiHeader.biSizeImage =
- width * height * (bmi_.bmiHeader.biBitCount >> 3);
- //通过 reset 函数重新分配了内存,为 image_ 分配大小为 biSizeImage字节的内存空间
- image_.reset(new uint8_t[bmi_.bmiHeader.biSizeImage]);
- _rotate.reset(new uint8_t[width * height*3/2]);
- }
- // void CEgoWindow::WriteCanMessage(std::unordered_map<int32_t, cannet_frame>& node, bool)
- // {
- // if (_channelcreated == false || node.empty()) return;
- // RemoNet::CCCanMesage Req;
- // Req.set_islidar(false);
- // for (auto& it : node)
- // {
- // // if (it.second.canid == htonl(0x486))
- // {
- // auto m = Req.add_message();
- // m->set_head(it.second.dlc);
- // m->set_canid(it.second.canid);
- // m->set_data(it.second.data, 8);
- // // m->set_islidar(false);
- // }
- // // it->second.canid
- // }
- // MessageHead Head;
- // CIOBuffer pBuffer;
- // Head.Command = RemoNet::CC_CAN;
- // Head.Length = Req.ByteSizeLong();
- // Head.Serialize(pBuffer.Buffer);
- // auto ptr = pBuffer.Buffer + MessageHead::Size();
- // Req.SerializeToArray(ptr, Head.Length);
- // pBuffer.Length = MessageHead::Size() + Head.Length;
- // _peerconnection->SendData(&pBuffer);
- // }
- void CEgoWindow::Process(CIOBuffer* pBuffer)
- {
- Message* message = reinterpret_cast<Message*>(pBuffer->Buffer);
- switch (message->cmd)
- {
- case WM_NOTIFY_REP:
- OnNotifyRep((int32_t)message->param_l);
- break;;
- case WM_NOTIFY_ANSWER:
- OnNotifyAnswer((CIOBuffer*)message->param_l);
- break;
- /*case WM_NOTIFY_LEAVE:
- OnNotifyLeave();
- break;
- */
- case WM_NOTIFY_CANDIDATE:
- OnNotifyCandidate((CIOBuffer*)message->param_l);
- break;
- case WM_NOTIFY_OFFER:
- OnNotifyOffer((CIOBuffer*)message->param_l);
- break;
- case WM_ASK_CHANNEL:
- OnAskDataChannel();
- break;
- case WM_ASK_PING:
- OnAskPing();
- break;
- case WM_ASK_VIDEOREQ:
- OnAskVideoReq();
- break;
- }
- }
- void CEgoWindow::OnNotifyAnswer(CIOBuffer* pBuffer)
- {
- AnswerDesc* desc = (AnswerDesc*)pBuffer->Buffer;
- const char* type = desc->type;
- const char* sdp = desc->sdp;
- _peerconnection->SetRemoteDescription(type, sdp);
- pBuffer->Release(__FILE__, __LINE__);
- PostMessage(WM_ASK_CHANNEL);
- // DelayDataChannel();
- }
- void CEgoWindow::OnNotifyOffer(CIOBuffer* pBuffer)
- {
- OfferDesc* desc = (OfferDesc*)pBuffer->Buffer;
- auto type = desc->type;
- auto sdp = desc->sdp;
- _peerconnection->SetRemoteDescription(type, sdp);
- _peerconnection->CreateAnswer();
- pBuffer->Release(__FILE__, __LINE__);
- }
- void CEgoWindow::OnNotifyCandidate(CIOBuffer* pBuffer)
- {
- CandidateDesc* desc = (CandidateDesc*)pBuffer->Buffer;
- auto candidate = desc->candidate;
- auto sdp_mid = desc->sdp_mid;
- auto sdp_mline_index = desc->sdp_mline_index;
- _peerconnection->AddIceCandidate(candidate, sdp_mline_index, sdp_mid);
- pBuffer->Release(__FILE__, __LINE__);
- }
-
- void CEgoWindow::OnNotifyLeave()
- {
-
- if (start_) return;
- assert(start_ == false);
- StopPing();
- // _channelcreated = false;
- _peer = -1;
- /*if (_pos == RenderPosition::FRONT)
- {
- _peerconnection->RemoveLocalAudioTrack();
- }
- */
- if (_peerconnection != nullptr)
- {
- _peerconnection->Close();
- _peerconnection.reset();
- _peerconnection = nullptr;
- }
- //ddd
- //image_ = nullptr;
- if (_render != nullptr)
- //_render->OnRender(image_,0,0);
- _render->Empty();
- _control = ControlState::Check;
- }
- /*
- void CEgoWindow::DelayDataChannel()
- {
- _delayThread = std::thread(&CEgoWindow::AskDataChannel, this);
- _delayThread.detach();
- }
- void CEgoWindow::DelayStartPing()
- {
- _delayThread = std::thread(&CEgoWindow::StartPing, this);
- _delayThread.detach();
- }
- */
- void CEgoWindow::OnIdle()
- {
- //发送ping给下位机
- if (!_ping) return;
- if (_pos==RenderPosition::FRONT)
- {
- int64_t tick=GetTickCount64();
- RemoNet::CCPing Req;
- Req.set_tick(tick);
- CIOBuffer Buffer;
- MessageHead Head;
- Head.Command = RemoNet::CC_Ping;
- Head.Length = Req.ByteSizeLong();
- Head.Serialize(Buffer.Buffer);
- auto ptr = Buffer.Buffer + MessageHead::Size();
- Req.SerializeToArray(ptr, Head.Length);
- Buffer.Length = Head.Length + MessageHead::Size();
- //此处增加ping保护
- if(_peerconnection!= nullptr&&_peerconnection->bReadyChannel)
- _peerconnection->SendData(Buffer);
- }
- }
- void CEgoWindow::OnAskPing()
- {
- Sleep(300);
- _control = ControlState::Process;
- _ping = true;
- }
- void CEgoWindow::StopPing()
- {
- _ping = false;
- }
- void CEgoWindow::SetControlState(ControlState state)
- {
- _control = state;
- }
- void CEgoWindow::OnAskDataChannel()
- {
- Sleep(100);
- if (_peerconnection == nullptr) return;
- _peerconnection->SetDataReady();
- RemoNet::CCAskDataChannel Req;
-
- CIOBuffer Buffer;
- MessageHead Head;
- Head.Command = RemoNet::CC_ASKDATACHANNEL;
- Head.Length = Req.ByteSizeLong();
- Head.Serialize(Buffer.Buffer);
- auto ptr = Buffer.Buffer + MessageHead::Size();
- Req.SerializeToArray(ptr, Head.Length);
- Buffer.Length = Head.Length + MessageHead::Size();
- //_peerconnection->SendData(Buffer);
- //此处增加ping保护
- if (_peerconnection != nullptr && _peerconnection->bReadyChannel)
- _peerconnection->SendData(Buffer);
-
- }
- /*
- void CEgoWindow::DelayNextVideoReq()
- {
-
- _delayThread = std::thread(&CEgoWindow::AskVideoReq, this);
- _delayThread.detach();
- }
- */
- //请求视频数据
- void CEgoWindow::OnAskVideoReq()
- {
- Sleep(200);
- _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
- }
- /*
- void CEgoWindow::CreateVideoReq()
- {
- _client->GetSocketClient()->WriteVideoReq(_peer, _pos);
- }
- */
- void CEgoWindow::SetPeer(int32_t peer)
- {
- _peer = peer;
- }
- void CEgoWindow::SendData(CIOBuffer& pBuffer)
- {
- if(_peerconnection!=nullptr)
- _peerconnection->SendData(pBuffer);
- }
-
- CEgoClient* CEgoWindow::GetEgoClient()
- {
- return _client;
- }
- ControlState CEgoWindow::GetControlState()
- {
- return _control;;
- }
|