WebRTC[4]-WebRTC中JitterBuffer的运行机制
目录
前言
正文
audio_jitter_buffer_max_packets
jitter_buffer_min_delay_ms
结论
WebRTC版本:m76
前言
正文
audio_jitter_buffer_max_packets
jitter_buffer_min_delay_ms
结论
前言
众多周知,WebRTC凭借自身非常完美的JitterBuffer控制机制能够适应各种网络抖动和异常情况,从而保证声音和画面的流畅播放。今天,我们就从WebRTC对音频的处理逻辑中一窥究竟。正文
大家都知道,实际的网络总是非常复杂的,存在各种丢包和抖动等异常情况,视频经常会遇到卡顿、花屏等问题。所以,在接收端对接收的数据做一个缓冲处理是非常有必要的。如果是内部专用网络,一般能够保证非常稳定的网络状态,在一定程度上保证没有丢包,没有抖动和延时,那么接收端不需要做其他的缓存处理逻辑,拿到音频和视频数据直接播放就好了,效果也一定不会差。所以,针对实际的网络情况,在WebRTC中自然就会存在专门的缓存处理模块,它就是我们今天要了解的JitterBuffer,今天我们就来看看它在WebRTC中的使用情况。WebRTC版本:m76
audio_jitter_buffer_max_packets
WebRTC有专门处理音频的引擎模块WebRtcVoiceEngine,它在初始化时,就设置了音频数据包的最大缓存buffer。void WebRtcVoiceEngine::Init() {JitterBuffer的控制单位有时间也有个数,比如配置参数 audio_jitter_buffer_max_packets 的单位是个数,默认值是200,代码:
RTC_DCHECK(worker_thread_checker_.IsCurrent());
RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::Init";
// TaskQueue expects to be created/destroyed on the same thread.
low_priority_worker_queue_.reset(
new rtc::TaskQueue(task_queue_factory_->CreateTaskQueue(
"rtc-low-prio", webrtc::TaskQueueFactory::Priority::LOW)));
// Load our audio codec lists.
RTC_LOG(LS_INFO) << "Supported send codecs in order of preference:";
send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders());
for (const AudioCodec& codec : send_codecs_) {
RTC_LOG(LS_INFO) << ToString(codec);
}
RTC_LOG(LS_INFO) << "Supported recv codecs in order of preference:";
recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders());
for (const AudioCodec& codec : recv_codecs_) {
RTC_LOG(LS_INFO) << ToString(codec);
}
// Connect the ADM to our audio path. adm()->RegisterAudioCallback(audio_state()->audio_transport()); // Set default engine options. { AudioOptions options; options.echo_cancellation = true; options.auto_gain_control = true; options.noise_suppression = true; options.highpass_filter = true; options.stereo_swapping = false; options.audio_jitter_buffer_max_packets = 200; options.audio_jitter_buffer_fast_accelerate = false; options.audio_jitter_buffer_min_delay_ms = 0; options.audio_jitter_buffer_enable_rtx_handling = false; options.typing_detection = true; options.experimental_agc = false; options.extended_filter_aec = false; options.delay_agnostic_aec = false; options.experimental_ns = false; options.residual_echo_detector = true; bool error = ApplyOptions(options); RTC_DCHECK(error); } initialized所有的options设置都会在方法 ApplyOptions 调用后启用。 等待音频流收到后,增加一个处理的音频流: 我们来看 AddRecvStream 方法,在其方法内部创建了一个 WebRtcAudioReceiveStream 对象实例用来接收音频数据,代码如下: WebRtcAudioReceiveStream构造函数调用时会决定是否使用 transport cc 以及 nack,其中 nack 默认值是5000ms,如果5秒内没有收到某个音频包就会发送 nack 通知。 参数转换到新的结构体后,调用了 RecreateAudioReceiveStream 私有方法。其内部逻辑如下: CreateAudioReceiveStream 方法创建了音频接收流的 AudioReceiveStream 的实例: 此时,我们会发现 jitter_buffer_min_delay_ms 也被传进来,它的单位是ms。 CreateChannelReceive 方法调用了 voe::CreateChannelReceive 方法,把上述两个 jitter_buffer 参数设置进去。 最终进入到 ChannelReceive 类中,参数 jitter_buffer_max_packets 和参数 jitter_buffer_min_delay_ms 也转换成 NetEQ 的属性参数,进入到 ACM 音频编码处理模块中。 在 NetEQ 中起到真正的作用。JitterBuffer 其实还是通过一定的缓存机制来实现流畅播放的,缓存一定是以延时作为代价的,延时越大,对抖动的过滤效果越好。目前,WebRTC能够对丢包、乱序、延时等异常情况做处理,进而保证视频平稳的播放,尽可能的避免出现明显视频的加速播放和缓慢播放现象。 WeRTC的JitterBuffer机制非常优秀,能够处理丢包、乱序、延时到达等异常情况,但这不是单一的算法所能实现的,需要借助NACK、FEC、FIR等相互配合。其他的算***在后续文章中进行介绍。
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
WebRTC工作原理精讲 文章被收录于专栏
WebRTC 作为当下最热门的实时音视频通讯框架,涉及非常多的过程,比如采集、编码、组包、发包、传输、收包、丢包重传、解封装、解码、音视频同步、渲染等,同时还包括很多功能特性,比如ANS、AGC、AEC,REMB、GCC、CNG、FEC、PLI、SVC等,需要一点点深入理解其中的奥秘。