| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |    2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 
|    3  * |    3  * | 
|    4  *  Use of this source code is governed by a BSD-style license |    4  *  Use of this source code is governed by a BSD-style license | 
|    5  *  that can be found in the LICENSE file in the root of the source |    5  *  that can be found in the LICENSE file in the root of the source | 
|    6  *  tree. An additional intellectual property rights grant can be found |    6  *  tree. An additional intellectual property rights grant can be found | 
|    7  *  in the file PATENTS.  All contributing project authors may |    7  *  in the file PATENTS.  All contributing project authors may | 
|    8  *  be found in the AUTHORS file in the root of the source tree. |    8  *  be found in the AUTHORS file in the root of the source tree. | 
|    9  */ |    9  */ | 
|   10  |   10  | 
|   11 #include "webrtc/modules/pacing/packet_router.h" |   11 #include "webrtc/modules/pacing/packet_router.h" | 
|   12  |   12  | 
|   13 #include "webrtc/base/atomicops.h" |   13 #include "webrtc/base/atomicops.h" | 
|   14 #include "webrtc/base/checks.h" |   14 #include "webrtc/base/checks.h" | 
 |   15 #include "webrtc/base/timeutils.h" | 
|   15 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |   16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | 
|   16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |   17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 
|   17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |   18 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 
|   18  |   19  | 
|   19 namespace webrtc { |   20 namespace webrtc { | 
|   20  |   21  | 
|   21 PacketRouter::PacketRouter() : transport_seq_(0) { |   22 PacketRouter::PacketRouter() | 
 |   23     : last_remb_time_ms_(rtc::TimeMillis()), | 
 |   24       last_send_bitrate_bps_(0), | 
 |   25       transport_seq_(0) { | 
|   22   pacer_thread_checker_.DetachFromThread(); |   26   pacer_thread_checker_.DetachFromThread(); | 
|   23 } |   27 } | 
|   24  |   28  | 
|   25 PacketRouter::~PacketRouter() { |   29 PacketRouter::~PacketRouter() { | 
|   26   RTC_DCHECK(rtp_send_modules_.empty()); |   30   RTC_DCHECK(rtp_send_modules_.empty()); | 
|   27   RTC_DCHECK(rtp_receive_modules_.empty()); |   31   RTC_DCHECK(rtp_receive_modules_.empty()); | 
|   28 } |   32 } | 
|   29  |   33  | 
|   30 void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module) { |   34 void PacketRouter::AddSendRtpModule(RtpRtcp* rtp_module) { | 
|   31   rtc::CritScope cs(&modules_crit_); |   35   rtc::CritScope cs(&modules_crit_); | 
|   32   RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), |   36   RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), | 
|   33                        rtp_module) == rtp_send_modules_.end()); |   37                        rtp_module) == rtp_send_modules_.end()); | 
 |   38   if (rtp_send_modules_.empty() && !rtp_receive_modules_.empty()) { | 
 |   39     rtp_receive_modules_.front()->SetREMBStatus(false); | 
 |   40   } | 
 |   41  | 
|   34   // Put modules which can use regular payload packets (over rtx) instead of |   42   // Put modules which can use regular payload packets (over rtx) instead of | 
|   35   // padding first as it's less of a waste |   43   // padding first as it's less of a waste | 
|   36   if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) { |   44   if ((rtp_module->RtxSendStatus() & kRtxRedundantPayloads) > 0) { | 
 |   45     if (!rtp_send_modules_.empty()) { | 
 |   46       rtp_send_modules_.front()->SetREMBStatus(false); | 
 |   47     } | 
|   37     rtp_send_modules_.push_front(rtp_module); |   48     rtp_send_modules_.push_front(rtp_module); | 
 |   49     rtp_module->SetREMBStatus(true); | 
|   38   } else { |   50   } else { | 
 |   51     if (rtp_send_modules_.empty()) { | 
 |   52       rtp_module->SetREMBStatus(true); | 
 |   53     } | 
 |   54  | 
|   39     rtp_send_modules_.push_back(rtp_module); |   55     rtp_send_modules_.push_back(rtp_module); | 
|   40   } |   56   } | 
|   41 } |   57 } | 
|   42  |   58  | 
|   43 void PacketRouter::RemoveSendRtpModule(RtpRtcp* rtp_module) { |   59 void PacketRouter::RemoveSendRtpModule(RtpRtcp* rtp_module) { | 
|   44   rtc::CritScope cs(&modules_crit_); |   60   rtc::CritScope cs(&modules_crit_); | 
|   45   RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), |   61   RTC_DCHECK(std::find(rtp_send_modules_.begin(), rtp_send_modules_.end(), | 
|   46                        rtp_module) != rtp_send_modules_.end()); |   62                        rtp_module) != rtp_send_modules_.end()); | 
|   47   rtp_send_modules_.remove(rtp_module); |   63   rtp_send_modules_.remove(rtp_module); | 
 |   64   rtp_module->SetREMBStatus(false); | 
 |   65   if (!rtp_send_modules_.empty()) { | 
 |   66     rtp_send_modules_.front()->SetREMBStatus(true); | 
 |   67   } else if (!rtp_receive_modules_.empty()) { | 
 |   68     rtp_receive_modules_.front()->SetREMBStatus(true); | 
 |   69   } | 
|   48 } |   70 } | 
|   49  |   71  | 
|   50 void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module) { |   72 void PacketRouter::AddReceiveRtpModule(RtpRtcp* rtp_module) { | 
|   51   rtc::CritScope cs(&modules_crit_); |   73   rtc::CritScope cs(&modules_crit_); | 
|   52   RTC_DCHECK(std::find(rtp_receive_modules_.begin(), rtp_receive_modules_.end(), |   74   RTC_DCHECK(std::find(rtp_receive_modules_.begin(), rtp_receive_modules_.end(), | 
|   53                        rtp_module) == rtp_receive_modules_.end()); |   75                        rtp_module) == rtp_receive_modules_.end()); | 
 |   76   if (rtp_send_modules_.empty() && rtp_receive_modules_.empty()) { | 
 |   77     rtp_module->SetREMBStatus(true); | 
 |   78   } | 
|   54   rtp_receive_modules_.push_back(rtp_module); |   79   rtp_receive_modules_.push_back(rtp_module); | 
|   55 } |   80 } | 
|   56  |   81  | 
|   57 void PacketRouter::RemoveReceiveRtpModule(RtpRtcp* rtp_module) { |   82 void PacketRouter::RemoveReceiveRtpModule(RtpRtcp* rtp_module) { | 
|   58   rtc::CritScope cs(&modules_crit_); |   83   rtc::CritScope cs(&modules_crit_); | 
|   59   const auto& it = std::find(rtp_receive_modules_.begin(), |   84   const auto& it = std::find(rtp_receive_modules_.begin(), | 
|   60                              rtp_receive_modules_.end(), rtp_module); |   85                              rtp_receive_modules_.end(), rtp_module); | 
|   61   RTC_DCHECK(it != rtp_receive_modules_.end()); |   86   RTC_DCHECK(it != rtp_receive_modules_.end()); | 
|   62   rtp_receive_modules_.erase(it); |   87   rtp_receive_modules_.erase(it); | 
 |   88   if (rtp_send_modules_.empty()) { | 
 |   89     rtp_module->SetREMBStatus(false); | 
 |   90     if (!rtp_receive_modules_.empty()) { | 
 |   91       rtp_receive_modules_.front()->SetREMBStatus(true); | 
 |   92     } | 
 |   93   } | 
|   63 } |   94 } | 
|   64  |   95  | 
|   65 bool PacketRouter::TimeToSendPacket(uint32_t ssrc, |   96 bool PacketRouter::TimeToSendPacket(uint32_t ssrc, | 
|   66                                     uint16_t sequence_number, |   97                                     uint16_t sequence_number, | 
|   67                                     int64_t capture_timestamp, |   98                                     int64_t capture_timestamp, | 
|   68                                     bool retransmission, |   99                                     bool retransmission, | 
|   69                                     const PacedPacketInfo& pacing_info) { |  100                                     const PacedPacketInfo& pacing_info) { | 
|   70   RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread()); |  101   RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread()); | 
|   71   rtc::CritScope cs(&modules_crit_); |  102   rtc::CritScope cs(&modules_crit_); | 
|   72   for (auto* rtp_module : rtp_send_modules_) { |  103   for (auto* rtp_module : rtp_send_modules_) { | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  114     // time the CAS operation was executed. Thus, if prev_seq is returned, the |  145     // time the CAS operation was executed. Thus, if prev_seq is returned, the | 
|  115     // operation was successful - otherwise we need to retry. Saving the |  146     // operation was successful - otherwise we need to retry. Saving the | 
|  116     // return value saves us a load on retry. |  147     // return value saves us a load on retry. | 
|  117     prev_seq = rtc::AtomicOps::CompareAndSwap(&transport_seq_, desired_prev_seq, |  148     prev_seq = rtc::AtomicOps::CompareAndSwap(&transport_seq_, desired_prev_seq, | 
|  118                                               new_seq); |  149                                               new_seq); | 
|  119   } while (prev_seq != desired_prev_seq); |  150   } while (prev_seq != desired_prev_seq); | 
|  120  |  151  | 
|  121   return new_seq; |  152   return new_seq; | 
|  122 } |  153 } | 
|  123  |  154  | 
|  124 bool PacketRouter::SendFeedback(rtcp::TransportFeedback* packet) { |  155 void PacketRouter::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs, | 
 |  156                                            uint32_t bitrate_bps) { | 
 |  157   const int kRembSendIntervalMs = 200; | 
 |  158  | 
 |  159   // % threshold for if we should send a new REMB asap. | 
 |  160   const uint32_t kSendThresholdPercent = 97; | 
 |  161  | 
 |  162   int64_t now_ms = rtc::TimeMillis(); | 
 |  163   { | 
 |  164     rtc::CritScope lock(&remb_crit_); | 
 |  165  | 
 |  166     // If we already have an estimate, check if the new total estimate is below | 
 |  167     // kSendThresholdPercent of the previous estimate. | 
 |  168     if (last_send_bitrate_bps_ > 0) { | 
 |  169       uint32_t new_remb_bitrate_bps = | 
 |  170           last_send_bitrate_bps_ - bitrate_bps_ + bitrate_bps; | 
 |  171  | 
 |  172       if (new_remb_bitrate_bps < | 
 |  173           kSendThresholdPercent * last_send_bitrate_bps_ / 100) { | 
 |  174         // The new bitrate estimate is less than kSendThresholdPercent % of the | 
 |  175         // last report. Send a REMB asap. | 
 |  176         last_remb_time_ms_ = now_ms - kRembSendIntervalMs; | 
 |  177       } | 
 |  178     } | 
 |  179     bitrate_bps_ = bitrate_bps; | 
 |  180  | 
 |  181     if (now_ms - last_remb_time_ms_ < kRembSendIntervalMs) { | 
 |  182       return; | 
 |  183     } | 
 |  184     // NOTE: Updated if we intend to send the data; we might not have | 
 |  185     // a module to actually send it. | 
 |  186     last_remb_time_ms_ = now_ms; | 
 |  187     last_send_bitrate_bps_ = bitrate_bps; | 
 |  188   } | 
 |  189   SendRemb(bitrate_bps, ssrcs); | 
 |  190 } | 
 |  191  | 
 |  192 bool PacketRouter::SendRemb(uint32_t bitrate_bps, | 
 |  193                             const std::vector<uint32_t>& ssrcs) { | 
 |  194   rtc::CritScope lock(&modules_crit_); | 
 |  195   RtpRtcp* remb_module; | 
 |  196   if (!rtp_send_modules_.empty()) | 
 |  197     remb_module = rtp_send_modules_.front(); | 
 |  198   else if (!rtp_receive_modules_.empty()) | 
 |  199     remb_module = rtp_receive_modules_.front(); | 
 |  200   else | 
 |  201     return false; | 
 |  202   // The Add* and Remove* methods above ensure that this (and only this) module | 
 |  203   // has REMB enabled. REMB should be disabled on all other modules, because | 
 |  204   // otherwise, they will send REMB with stale info. | 
 |  205   RTC_DCHECK(remb_module->REMB()); | 
 |  206   remb_module->SetREMBData(bitrate_bps, ssrcs); | 
 |  207   return true; | 
 |  208 } | 
 |  209  | 
 |  210 bool PacketRouter::SendTransportFeedback(rtcp::TransportFeedback* packet) { | 
|  125   RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread()); |  211   RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread()); | 
|  126   rtc::CritScope cs(&modules_crit_); |  212   rtc::CritScope cs(&modules_crit_); | 
|  127   // Prefer send modules. |  213   // Prefer send modules. | 
|  128   for (auto* rtp_module : rtp_send_modules_) { |  214   for (auto* rtp_module : rtp_send_modules_) { | 
|  129     packet->SetSenderSsrc(rtp_module->SSRC()); |  215     packet->SetSenderSsrc(rtp_module->SSRC()); | 
|  130     if (rtp_module->SendFeedbackPacket(*packet)) |  216     if (rtp_module->SendFeedbackPacket(*packet)) | 
|  131       return true; |  217       return true; | 
|  132   } |  218   } | 
|  133   for (auto* rtp_module : rtp_receive_modules_) { |  219   for (auto* rtp_module : rtp_receive_modules_) { | 
|  134     packet->SetSenderSsrc(rtp_module->SSRC()); |  220     packet->SetSenderSsrc(rtp_module->SSRC()); | 
|  135     if (rtp_module->SendFeedbackPacket(*packet)) |  221     if (rtp_module->SendFeedbackPacket(*packet)) | 
|  136       return true; |  222       return true; | 
|  137   } |  223   } | 
|  138   return false; |  224   return false; | 
|  139 } |  225 } | 
|  140  |  226  | 
|  141 }  // namespace webrtc |  227 }  // namespace webrtc | 
| OLD | NEW |