webrtc-PacedSender

PacedSender
发送节拍器,控制发送的节奏,大概5ms一次,发送比较均匀

使用的内部类

  1. PacedSender::IntervalBudget
    根据设置的码率,计算这个时间间隔(IncreaseBudget(delta_time_ms) 最大kWindowMs = 500)可以发送的字节数,
    随着时间流逝剩余可以发送的字节数也会变得越来越小

      (1.)设置码率
     	     void set_target_rate_kbps(int target_rate_kbps) {
     		    target_rate_kbps_ = target_rate_kbps;
     	        //根据码率设置kWindowMs间隔内可以发送的字节数
     		    bytes_remaining_ =
     		        std::max(-kWindowMs * target_rate_kbps_ / 8, bytes_remaining_);
     		  }
    
      (2.)增加delta_time_ms长时间数据量 
       void IncreaseBudget(int64_t delta_time_ms) {
         int64_t bytes = target_rate_kbps_ * delta_time_ms / 8;
         if (bytes_remaining_ < 0) {		
     		//上一次使用过度了,上一个间隔发送的数据量有点大,平均到这一次上	      
             bytes_remaining_ = bytes_remaining_ + bytes;
         } else {
     		//  未充分使用上一个间隔,剩下的时间还可以发送这么多字节	      
             bytes_remaining_ = bytes;
         }
       }
    
       (3.) 已经发送了这么多数据了
       void UseBudget(size_t bytes) {
         bytes_remaining_ = std::max(bytes_remaining_ - static_cast<int>(bytes),
                                     -kWindowMs * target_rate_kbps_ / 8);
     	//  负值表示多发送了字节数,就是这个间隔发送过多
       }
    
      (4.) 获取还可以发送多少数据
       size_t bytes_remaining() const {
         return static_cast<size_t>(std::max(0, bytes_remaining_));
       }
    
  2. PacedSender::PacketQueue 保存待发送包信息队列
    插入支持优先级,基本上队列的基本操作

       //  计算一个包在队列中待的平均时长		 
       int64_t AverageQueueTimeMs() const {
         if (prio_queue_.empty())
           return 0;
         return queue_time_sum_ / packet_list_.size();
       }
    

节拍发送器

  1. 主要成员

     PacedSender{
        
        //节拍内发送数据的上限控制
        paced_sender::IntervalBudget media_budget_;
        //节拍内发送数据的下限控制,不够就发送rtp填充数据
        paced_sender::IntervalBudget padding_budget_
        //队列
        paced_sender::PacketQueue> packets_;
     }
    
  2. 插入数据,这个简单就是队列中插数据

     void InsertPacket(RtpPacketSender::Priority priority,
                                    uint32_t ssrc,
                                    uint16_t sequence_number,
                                    int64_t capture_time_ms,
                                    size_t bytes,
                                    bool retransmission)
    
  3. 节拍驱动循环

    如果码率探测过程中,则会限制发送的最大大小,限制一次不能发送太多字节

    void Process(){

       { **//1. 根据一包在队列中的平均时长计算出清空对象需要的码率,更新码率限制的上限**
         size_t queue_size_bytes = packets_->SizeInBytes();
         if (queue_size_bytes > 0) {
           packets_->UpdateQueueTime(clock_->TimeInMilliseconds());
     	  //  kMaxQueueLengthMs 一个包在队列中的最大时长
           int64_t avg_time_left_ms = std::max<int64_t>(
               1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs());			  
     	  //  根据历史一个包在队列中的平均时长,计算发送队列中的所有的这些数据需要的最小码率
           int min_bitrate_needed_kbps =
               static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms);
           if (min_bitrate_needed_kbps > target_bitrate_kbps)
             target_bitrate_kbps = min_bitrate_needed_kbps;
         }
     
         media_budget_->set_target_rate_kbps(target_bitrate_kbps);
     
     	    elapsed_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
     	    UpdateBudgetWithElapsedTime(elapsed_time_ms);
      }
    
    
      //**2. 控制rtp有效数据的发送**
       while (!packets_->Empty()) {
         const paced_sender::Packet& packet = packets_->BeginPop();
         //  SendPacket内部会根据最大码率限制进行发送,如果达到了最大码率则不发送了
         if (SendPacket(packet, pacing_info)) {		      
           bytes_sent += packet.bytes;
           packets_->FinalizePop(packet);
           if (is_probing && bytes_sent > recommended_probe_size)
     		 // 码率探测过程中,控制码率不要大于这个 recommended_probe_size
             break;
         } else {
           // Send failed, put it back into the queue.
           packets_->CancelPop(packet);
           break;
         }
       }
    
    
       //**3. 看一下限制的最小发送码率是否达到了如果没达到则发送pad包**
       if (packets_->Empty() && !paused_) {   
         if (packet_counter_ > 0) {
           int padding_needed =
               static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent)
                                           : padding_budget_->bytes_remaining());
     	  
     	  //  这为了保证一个最小码率			  
           if (padding_needed > 0)
             bytes_sent += SendPadding(padding_needed, pacing_info);
         }
       }	}
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值