WebRTC的JitterBuffer笔记

 接收类图不全

一  主要的类

类video_coding::PacketBuffer是接收RTP包,类RtpVideoStreamReceiver2中有用到。

packet_buffer_(clock_, kPacketBufferStartSize, PacketBufferMaxSize()),最小值512,最大2048。

类video_coding::FrameBuffer是一帧完整的视频数据,类VideoReceiveStream2中有用到。

constexpr size_t kMaxFramesBuffered = 800; //最大缓存800帧

二  判断一帧数据是否完整

判断第一包、最后一包是否在一帧中

parsed_payload->type.Video.is_first_packet_in_frame = first_fragment;

//FU_A第二字节的SER的S

video_header.is_last_packet_in_frame |= rtp_packet.Marker(); //RTP包的mark位

void RtpVideoStreamReceiver2::OnInsertedPacket(
    video_coding::PacketBuffer::InsertResult result) {

   for (auto& packet : result.packets) {
    ...
    //把rtp包写成完整一帧数据,给video_coding::RtpFrameReferenceFinder管理
    OnAssembledFrame(std::make_unique<video_coding::RtpFrameObject>()
   }
}

RtpVideoStreamReceiver2::OnAssembledFrame(
--| reference_finder_->ManageFrame(std::move(frame));

三  帧间完整性判断—gop--没懂

把最后一包的seq作为pid-图片唯一标识。

四  FrameBuffer用在那 ? 解码

VideoReceiveStream2::OnCompleteFrame()
frame_buffer_->InsertFrame(std::move(frame));


VideoReceiveStream2::StartNextDecode() {
//NextFrame()获得frame,给HandleEncodedFrame解码
frame_buffer_->NextFrame()
 --|  frame = absl::WrapUnique(GetNextFrame());	
HandleEncodedFrame(std::move(frame));
}

五  JitterDelay的计算

//卡尔曼滤波器:在不确定的数据中估算出最优结果的算法。
//用卡尔曼kalman滤波估计(或预测) JitterDelay
计算公式如下:跟最大帧长度,平均帧长度等有关
JitterDelay = theta[0] * (MaxFS – AvgFS) + [noiseStdDevs * sqrt(varNoise) – noiseStdDevOffset]

double VCMJitterEstimator::CalculateEstimate(),返回值就是JitterDelay。

VCMJitterEstimator::UpdateEstimate
--| KalmanEstimateChannel(frameDelayMS, deltaFS);--更新公式参数的值

//获取jitter估计值,单位是毫秒
int VCMJitterEstimator::GetJitterEstimate(
    double rttMultiplier,
    absl::optional<double> rttMultAddCapMs)

// Updates the estimates with the new measurements.
void VCMJitterEstimator::UpdateEstimate(int64_t frameDelayMS,
                                        uint32_t frameSizeBytes,
                                        bool incompleteFrame /* = false */) 

六  JitterDelay:1 作用于从接收队列取数据的时间(意义在那?)  2 赋值给视频帧渲染时间

//帧间延时-->JitterDelay-->wait_ms:从接收队列取frame的时间
//wait_ms值在[0、3000]
int64_t VCMTiming::RenderTimeMsInternal(
{
  int64_t estimated_complete_time_ms =
      ts_extrapolator_->ExtrapolateLocalTime(frame_timestamp); //?
  return estimated_complete_time_ms + actual_delay;
}


EncodedFrame* FrameBuffer::GetNextFrame() 
{
 //帧间延时frame_delay传给滤波
 if (inter_frame_delay_.CalculateDelay(first_frame->Timestamp(),
                                          &frame_delay, receive_time_ms)) {
      jitter_estimator_.UpdateEstimate(frame_delay, superframe_size);
 }
 ...
 timing_->SetJitterDelay(
        jitter_estimator_.GetJitterEstimate(rtt_mult, rtt_mult_add_cap_ms));
 ...
}

int64_t FrameBuffer::FindNextFrame(int64_t now_ms) 
{
  EncodedFrame* frame = frame_it->second.frame.get();

  if (frame->RenderTime() == -1) {		
        frame->SetRenderTime(timing_->RenderTimeMs(frame->Timestamp(), now_ms));		
  }
  //frame->RenderTime()即期望渲染时间-当前时间-解码所需时间-渲染延迟时间(值10ms)
  wait_ms = timing_->MaxWaitingTime(frame->RenderTime(), now_ms);
  
  return wait_ms;
}

七 RenderTime视频帧渲染时间,算出渲染等待时间

看有的文章说,动态调整jitterbuffer大小,没有,只是调整了渲染的时间。

void IncomingVideoStream::Dequeue() {  
  absl::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
  if (frame_to_render)
    callback_->OnFrame(*frame_to_render);
    //即VideoReceiveStream2::OnFrame(

 //过wait_time,再去渲染
 if (render_buffers_.HasPendingFrames()) {
    uint32_t wait_time = render_buffers_.TimeToNextFrameRelease();	
    incoming_render_queue_.PostDelayedTask([this]() { Dequeue(); }, wait_time);
  }
}


uint32_t VideoRenderFrames::TimeToNextFrameRelease() {
 //render_time_ms()是frame->SetRenderTime()设置进去的时间。
 const int64_t time_to_release = incoming_frames_.front().render_time_ms() -
                                  render_delay_ms_ - rtc::TimeMillis();

 return time_to_release < 0 ? 0u : static_cast<uint32_t>(time_to_release);
} 
//赋值的地方
frame_info.renderTimeMs = frame.RenderTimeMs();
decodedImage.set_timestamp_us(frameInfo->renderTimeMs *
                                rtc::kNumMicrosecsPerMillisec);

八 Jitterbuffer调优参数 

1 rtp_video_header.playout_delay,rtp扩展头字段。

2 jitterbuffer和nack模块关系?nack功能需要取缓存的rtp包。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WebRTC抖动缓冲器是一种用于处理网络延迟和抖动的技术。它可以在音频和视频传输过程中缓存数据包,以确保数据包按照正确的顺序到达接收方,并且可以在需要时进行重传。抖动缓冲器可以帮助提高音频和视频的质量,减少延迟和丢包率,从而提高用户体验。 ### 回答2: WebRTC jitterbuffer是一种用于优化WebRTC音频和视频流的技术。在网络通信中,数据包的传输不可避免地会出现延迟,这可能导致音频和视频流的中断和卡顿。为了解决这个问题,WebRTC jitterbuffer使用一种缓冲机制,以平衡延迟和数据传输的完整性。 WebRTC jitterbuffer接收来自网络的音频和视频帧,并通过调整它们的播放时间来平衡延迟。如果网络不稳定或拥塞,WebRTC jitterbuffer会增加缓冲,以确保音频或视频流的连续性。当网络稳定时,WebRTC jitterbuffer会逐渐减少缓冲的大小,以减少延迟和改善实时反应性。 此外,WebRTC jitterbuffer还可根据特定的需求进行定制。例如,它可以根据网络质量和设备性能进行动态调整。它还可以通过将音频和视频流分别处理,来更好地优化总体性能。 总的来说,WebRTC jitterbuffer是一种有效的技术,可以帮助WebRTC用户克服网络延迟的问题,提供更好的音频和视频通信体验。随着WebRTC应用程序的广泛应用,WebRTC jitterbuffer的重要性也逐渐凸显。 ### 回答3: WebRTC JitterBuffer – 意指 WebRTC 的抖动缓冲器,是一种数据处理机制,主要用于解决因网络传输延迟不一致导致的数据抖动或突变问题。WebRTC 向来被视为一种适用于实时实时通信场景的音视频传输协议,依靠其先进的传输技术,WebRTC 能够将高品质的音视频数据进行实时传输,并保证在不同网络延迟下的稳定性和流畅性。 然而,由于公共互联网环境的不可预测性,很容易会遭遇到网络延迟、数据丢包等问题,从而导致用户在接收音视频时出现抖动的情况。这时候就需要使用 WebRTC JitterBuffer 来对数据进行处理,使其变得更加平滑,并对数据进行合理的延时处理。 WebRTC 抖动缓冲器的主要作用是针对网络抖动或突变对音视频数据进行一定的延迟处理,并从丢包数据中恢复丢失的数据。在 WebRTC 中,一般会采用混合适应性抖动缓冲器(Hybrid Adaptive Jitter Buffer)的机制来进行处理,具体详见以下的处理流程: 1.接收数据 - WebRTC 首先会收集音视频数据,并对数据进行封装和编码,然后通过 UDP 协议进行传输。 2.处理网络抖动 - 当数据经过网络时,会因为网络延迟、网络丢包、网络拥塞等原因造成数据的抖动现象。WebRTC JitterBuffer 就会在此时进行响应,对抖动数据进行中间处理,从而使数据流畅而不受到抖动的影响。 3.延迟处理 - 当 WebRTC JitterBuffer 处理完抖动数据后,还可以对数据进行一定的延迟处理。这是因为,数据在传输过程中,很容易收到网络情况的影响,从而导致数据的突变现象。延迟处理可以缓解这一问题,并使音视频数据更平滑地呈现在用户面前。 4.数据解码 - 最后,WebRTC JitterBuffer 将处理好的音视频数据进行解码,然后交给音频或视频播放器进行渲染和播放。 综上所述,WebRTC JitterBuffer 可以说是 WebRTC 传输协议中重要的一个环节,通过它可以解决音视频传输过程中的抖动或突变问题,并保障了音视频数据的流畅和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值