一、前言
网上看到很多webrtc的JitterBuffer处理流程,都是介绍VCMJitterBuffer类的实现流程,不过手里的这个2019年的版本,发现webrtc已经不用这个机制了。原因还不清楚。
VCMJitterBuffer类的调用关系如下图,但是,VideoCodingModuleImpl、VideoReceiveStream、VideoStreamDecoder三个类,都没有调用VCMJitterBuffer的InsertPacket关键函数。
VCMJitterBuffer
->VCMReceiver
->VideoReceiver
->VideoCodingModuleImpl
VideoReceiveStream
VideoStreamDecoder
二、实现简介
走读最新的webrtc的JitterBuffer代码,发现实现的大概思想是,视频按照RTP报入队一个全局buffer,按照计算的一个jitter时间,pop一帧视频,送进解码器。
三、RTP入队流程
入队的核心函数如下:
->video_coding::PacketBuffer::InsertPacket
-------------------------将RTP报文缓存在data_buffer_中。
->RtpVideoStreamReceiver::OnReceivedFrame
-------------------------判断首帧是否是IDR,不是丢弃帧;是,调用ManageFrame。
->video_coding::RtpFrameReferenceFinder::ManageFrame
-------------------------判断帧间参考关系。若当前帧的参考帧没到,继续等。
->RtpVideoStreamReceiver::OnCompleteFrame
-------------------------继续传VideoReceiveStream::OnCompleteFrame
->internal::VideoReceiveStream::OnCompleteFrame
-------------------------继续传FrameBuffer::InsertFrame
->video_coding::FrameBuffer::InsertFrame
--------------------------对当前帧的参考关系、时间戳进行合法性判断。合法帧发送信号量,知会解码器取数据。
四、视频帧出队流程
出队的核心函数为:
->bool VideoReceiveStream::Decode
-------------------------解码器找frame_buffer要数据。配置等待超时时间kMaxWaitForFrameMs或kMaxWaitForKeyFrameMs
->FrameBuffer::ReturnReason FrameBuffer::NextFrame
-------------------------若当前帧OK,直接送给解码器。若当前帧不全,需要等wait_ms,超过wait_ms,直接跳下一帧。
->VCMTiming::MaxWaitingTime
--------------------------计算当前帧解码时间是否到,到就出帧,否则就等待。
等待时间=当前帧预计渲染时间-解码消耗时间-渲染模块耗时
因为这里是解码前,所以要把后面的解码+渲染时间扣除。
五、render_time_ms计算
VCMTiming::RenderTimeMs函数实现视频帧渲染时间的计算。
VCMTiming::RenderTimeMs
->VCMTiming::RenderTimeMsInternal
->VCMTiming::TargetDelayInternal
一帧视频的预期渲染时间是发送端发送时间+网络延时时间+解码时间+渲染模块耗时时间
发送端发送时间:可以根据发送报文的时间戳+接收第一帧视频的系统时间推算出来。
网络延时时间:可以参考《webrtc代码走读十六(Jitter延时的计算)》
解码时间:使用KalmanFilter算法,计算每帧视频解码时间。
渲染时间:根据硬件配置,是固定值。
1)发送端发送时间计算函数
TimestampExtrapolator::ExtrapolateLocalTime
2)网络延时时间计算函数
VCMJitterEstimator::GetJitterEstimate
3)解码时间计算函数
VCMCodecTimer::RequiredDecodeTimeMs
4)渲染时间
VideoReceiveStream::VideoReceiveStream函数
video_receiver_.SetRenderDelay(config_.render_delay_ms)代码配置固定值
六、渲染前判断wait_time
IncomingVideoStream::OnFrame
VideoRenderFrames::FrameToRender