webrtc网络适应性-泳道图
2019-03-13 18:54:24   0  举报             
     
         
 webrtc 数据包接收流程,包含nack、send-side-bwe、receive-side-bwe、jitterbuffer、codec、renderer等过程详解
    作者其他创作
 大纲/内容
 以callback的方式调用VideoReceiveStream::OnCompleteFrame,insert到frame_buffer
  RtpFrameReferenceFinder::ManageFramePidOrSeqNum
  receive-side-bwe
    带宽估计是按照ssrc分别处理的,存在各map,key是ssrc,value是detector(包含estimator的各种stastics数据)
  动态带宽估计(sendside-bwe、gcc两种),体现在sdp上是transport-cc和google-remb,sendside在rtp扩展头中有transportSequenceNumber字段(应该是按视频帧计数,是什么需要在发送方向看代码)。
  以h264为例,缓存pps和sps用来后续包的参数集的引用,校验和提取nalu,最后insert到packet_buffer中。
  解码完成后,videoframe以回调的方式传递给renderer,回调接口为VCMReceiveCallback::FrameToRender
  ReceiveSideCongestionController::WrappingBitrateEstimator::IncomingPacket
  RtpDemuxer::OnRtpPacket
  AsyncUDPSocket::OnReadEvent物理层异步接收网络数据包
  此为ARQ的主要处理过程,主要逻辑是通过记录最近接收的newest_seq_num_以及当前接收的seq判定是否存在丢包,加入到nack_list中(fec恢复的包不作处理),乱序收包更新nack_list,由nack_module定时器(20ms)发送rtcp nack报文。对于发送的rtcp nack的包,按照rtt延迟,进行batch发送nack,最大重传请求次数为10次nack_list积压过大时请求重传关键帧
  rtpdemuxer按照ssrc分别处理
  call module
  在多mid且为bundle的情况下,BaseChannel与SrtpTransport的关系是n:1,具体看设置remoteSDP的实现。demuxer可按照rtp扩展头信息中的mid或ssrc确定sink。basechannel通过RegisterRtpDemuxerSink接口实现与rtpdemuxer的sink注册。
  RtpVideoStreamReceiver::OnReceivedPayloadData
  packet_buffer_->InsertPacket(&packet)
  Call::NotifyBweOfReceivedPacket
  rtprtcp module
  由于在此处是由workthread异步队列处理且为同步调用来的,所以没有线程问题。但这样好吗?
  进行srtp的解密
  nack_module process timer(20ms)send rtcp nack
  VideoStreamDecoder::FrameToRenderincoming_video_stream_->OnFrame(video_frame);
  RtpStreamReceiverController::OnRtpPacket
  在此过程中,根据payload类型进行拆包操作,以h264为例,此过程进行FU-A和STAP-A两种格式的拆包,分析SPS和PPS信息,关键帧、一帧数据的包头、包尾,视频宽高。
  此时,一个track的包处理过程出现问题可能影响此终端的其他路视频,拔网线所有视频卡住可能是此原因造成的。 
  congestion controller
  p2p/pc module
  WebRtcVideoChannel::OnPacketReceived
  经P2PTransportChannel以signal/slot的方式传递数据包
  codec module
  此过程使用Jitter estimation计算decode delay和renderer delay,暂时没看明白。
  send-side-bwe
  video/voice engine
  以h264为例,其解码器是依赖ffmpeg 和x264的API实现的,通过回调方式返回decodedFrame
  RemoteEstimatorProxy::IncomingPacket
  此处涉及到fec包的处理,专门处理
  receive-side-bwe处理间隔为500ms,首先计算以帧为单位(timestamp相同)的两个包组的timestamp_delta、arrival_time_delta、size_delta输入kalman filter,其次将估计的timestame_delta输入过载检测器,判断网络状态(overuse、underuse、normal),目标码率控制器根据网络状态变化和当前码率计算目标码率。最后通过REMB报文发送至sender。
  在收到帧结尾的包时,根据seq、timestamp和一堆标识取出完整帧
  VideoReceiver::Decodedecoder->Decode进行解码
  每一个VideoReceiveStream实例包含一个解码线程decode_thread_(实时优先级)和一个rtp_video_stream_receiver_,解码线程和视频帧缓存线程共用frame_buffer,在此存在互斥锁。
  在此区分不同的mediachannel是因为DeliverPacket的失败后续处理不一致。mediachannel与basechannel为1:1。
  VideoReceiveStream::DecodeThreadFunction
  send-side-bwe只记录transportSequenceNumber相同情况下的first packet的packet arrival times,重传包不计算由module的定时器每隔100ms发送一个feedback,发送端做estimation。
  Call::DeliverRtp
  NackModule::OnReceivedPacket根据seq更新nack_list
  RtpTransport::OnReadPacketSrtpTransport::OnRtpPacketReceived
  这里采用了基于work线程的异步调用方法,同一个workthread处理所有包,此workthread即创建factory时传入的thread
  BaseChannel::OnPacketReceived
  根据帧的包组first seq、前一帧的最后一个包的seq、可参考的关键帧最后一个包序号(last_seq_num_gop_),进而判定该帧的状态是stash还是complete。此步骤主要进行帧的重排序。
  vcm module
  RtpVideoStreamReceiver::OnRtpPacket
  VideoReceiveStream::DecodeFrameBuffer::NextFrame
  FrameBuffer::InsertFrame
  RtpVideoStreamReceiver::ReceivePacket
  PacketBuffer::FindFrames
  peerconnection_client回调中的onaddtrack中将UI创建的renderer通过addorupdatesink接口添加至videobroadcast。videobroadcast通过VideoRtpReceiver::SetSink接口加入到mediachannel,进而保存至WebRtcVideoChannel::WebRtcVideoReceiveStream的sink_变量,WebRtcVideoReceiveStream接收上述的onframe回调后依次以sink->onframe的接口回调至前台,实现remote视频显示。
   
 
 
 
 
  0 条评论
 下一页
  
   
   
   
   
  
  
  
  
  
  
  
  
 