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 条评论
回复 删除
下一页