Home | History | Annotate | Download | only in rtcp
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/cast/rtcp/rtcp.h"
      6 
      7 #include "base/big_endian.h"
      8 #include "base/rand_util.h"
      9 #include "media/cast/cast_config.h"
     10 #include "media/cast/cast_defines.h"
     11 #include "media/cast/cast_environment.h"
     12 #include "media/cast/rtcp/rtcp_defines.h"
     13 #include "media/cast/rtcp/rtcp_receiver.h"
     14 #include "media/cast/rtcp/rtcp_sender.h"
     15 #include "media/cast/rtcp/rtcp_utility.h"
     16 #include "media/cast/transport/cast_transport_defines.h"
     17 
     18 namespace media {
     19 namespace cast {
     20 
     21 static const int kMaxRttMs = 10000;  // 10 seconds.
     22 static const int kMaxDelay = 2000;
     23 
     24 class LocalRtcpRttFeedback : public RtcpRttFeedback {
     25  public:
     26   explicit LocalRtcpRttFeedback(Rtcp* rtcp) : rtcp_(rtcp) {}
     27 
     28   virtual void OnReceivedDelaySinceLastReport(
     29       uint32 receivers_ssrc, uint32 last_report,
     30       uint32 delay_since_last_report) OVERRIDE {
     31     rtcp_->OnReceivedDelaySinceLastReport(receivers_ssrc, last_report,
     32                                           delay_since_last_report);
     33   }
     34 
     35  private:
     36   Rtcp* rtcp_;
     37 };
     38 
     39 class LocalRtcpReceiverFeedback : public RtcpReceiverFeedback {
     40  public:
     41   LocalRtcpReceiverFeedback(Rtcp* rtcp,
     42                             scoped_refptr<CastEnvironment> cast_environment)
     43       : rtcp_(rtcp), cast_environment_(cast_environment) {}
     44 
     45   virtual void OnReceivedSenderReport(
     46       const transport::RtcpSenderInfo& remote_sender_info) OVERRIDE {
     47     rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds,
     48                          remote_sender_info.ntp_fraction);
     49     if (remote_sender_info.send_packet_count != 0) {
     50       rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp,
     51                                    remote_sender_info.ntp_seconds,
     52                                    remote_sender_info.ntp_fraction);
     53     }
     54   }
     55 
     56   virtual void OnReceiverReferenceTimeReport(
     57       const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE {
     58     rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds,
     59                          remote_time_report.ntp_fraction);
     60   }
     61 
     62   virtual void OnReceivedSendReportRequest() OVERRIDE {
     63     rtcp_->OnReceivedSendReportRequest();
     64   }
     65 
     66   virtual void OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log)
     67       OVERRIDE {
     68     rtcp_->OnReceivedReceiverLog(receiver_log);
     69   }
     70 
     71  private:
     72   Rtcp* rtcp_;
     73   scoped_refptr<CastEnvironment> cast_environment_;
     74 };
     75 
     76 Rtcp::Rtcp(scoped_refptr<CastEnvironment> cast_environment,
     77            RtcpSenderFeedback* sender_feedback,
     78            transport::CastTransportSender* const transport_sender,
     79            transport::PacedPacketSender* paced_packet_sender,
     80            RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode,
     81            const base::TimeDelta& rtcp_interval, uint32 local_ssrc,
     82            uint32 remote_ssrc, const std::string& c_name,
     83            EventMediaType event_media_type)
     84     : cast_environment_(cast_environment),
     85       transport_sender_(transport_sender),
     86       rtcp_interval_(rtcp_interval),
     87       rtcp_mode_(rtcp_mode),
     88       local_ssrc_(local_ssrc),
     89       remote_ssrc_(remote_ssrc),
     90       c_name_(c_name),
     91       event_media_type_(event_media_type),
     92       rtp_receiver_statistics_(rtp_receiver_statistics),
     93       rtt_feedback_(new LocalRtcpRttFeedback(this)),
     94       receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)),
     95       rtcp_sender_(new RtcpSender(cast_environment, paced_packet_sender,
     96                                   local_ssrc, c_name)),
     97       last_report_truncated_ntp_(0),
     98       local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()),
     99       lip_sync_rtp_timestamp_(0),
    100       lip_sync_ntp_timestamp_(0),
    101       min_rtt_(base::TimeDelta::FromMilliseconds(kMaxRttMs)),
    102       number_of_rtt_in_avg_(0) {
    103   rtcp_receiver_.reset(new RtcpReceiver(cast_environment, sender_feedback,
    104                                         receiver_feedback_.get(),
    105                                         rtt_feedback_.get(), local_ssrc));
    106   rtcp_receiver_->SetRemoteSSRC(remote_ssrc);
    107 }
    108 
    109 Rtcp::~Rtcp() {}
    110 
    111 // static
    112 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) {
    113   DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet";
    114   if (length < kMinLengthOfRtcp) return false;
    115 
    116   uint8 packet_type = packet[1];
    117   if (packet_type >= transport::kPacketTypeLow &&
    118       packet_type <= transport::kPacketTypeHigh) {
    119     return true;
    120   }
    121   return false;
    122 }
    123 
    124 // static
    125 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) {
    126   DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet";
    127   uint32 ssrc_of_sender;
    128   base::BigEndianReader big_endian_reader(
    129       reinterpret_cast<const char*>(rtcp_buffer), length);
    130   big_endian_reader.Skip(4);  // Skip header
    131   big_endian_reader.ReadU32(&ssrc_of_sender);
    132   return ssrc_of_sender;
    133 }
    134 
    135 base::TimeTicks Rtcp::TimeToSendNextRtcpReport() {
    136   if (next_time_to_send_rtcp_.is_null()) {
    137     UpdateNextTimeToSendRtcp();
    138   }
    139   return next_time_to_send_rtcp_;
    140 }
    141 
    142 void Rtcp::IncomingRtcpPacket(const uint8* rtcp_buffer, size_t length) {
    143   RtcpParser rtcp_parser(rtcp_buffer, length);
    144   if (!rtcp_parser.IsValid()) {
    145     // Silently ignore packet.
    146     DLOG(ERROR) << "Received invalid RTCP packet";
    147     return;
    148   }
    149   rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser);
    150 }
    151 
    152 void Rtcp::SendRtcpFromRtpReceiver(
    153     const RtcpCastMessage* cast_message,
    154     const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events) {
    155   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
    156   uint32 packet_type_flags = 0;
    157 
    158   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    159   transport::RtcpReportBlock report_block;
    160   RtcpReceiverReferenceTimeReport rrtr;
    161 
    162   // Attach our NTP to all RTCP packets; with this information a "smart" sender
    163   // can make decisions based on how old the RTCP message is.
    164   packet_type_flags |= transport::kRtcpRrtr;
    165   ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction);
    166   SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction);
    167 
    168   if (cast_message) {
    169     packet_type_flags |= transport::kRtcpCast;
    170   }
    171   if (rtcp_events) {
    172     packet_type_flags |= transport::kRtcpReceiverLog;
    173   }
    174   if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) {
    175     packet_type_flags |= transport::kRtcpRr;
    176 
    177     report_block.remote_ssrc = 0;            // Not needed to set send side.
    178     report_block.media_ssrc = remote_ssrc_;  // SSRC of the RTP packet sender.
    179     if (rtp_receiver_statistics_) {
    180       rtp_receiver_statistics_->GetStatistics(
    181           &report_block.fraction_lost, &report_block.cumulative_lost,
    182           &report_block.extended_high_sequence_number, &report_block.jitter);
    183     }
    184 
    185     report_block.last_sr = last_report_truncated_ntp_;
    186     if (!time_last_report_received_.is_null()) {
    187       uint32 delay_seconds = 0;
    188       uint32 delay_fraction = 0;
    189       base::TimeDelta delta = now - time_last_report_received_;
    190       ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds,
    191                              &delay_fraction);
    192       report_block.delay_since_last_sr =
    193           ConvertToNtpDiff(delay_seconds, delay_fraction);
    194     } else {
    195       report_block.delay_since_last_sr = 0;
    196     }
    197     UpdateNextTimeToSendRtcp();
    198   }
    199   rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags,
    200                                         &report_block,
    201                                         &rrtr,
    202                                         cast_message,
    203                                         rtcp_events,
    204                                         target_delay_ms_);
    205 }
    206 
    207 void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time,
    208                                  uint32 current_time_as_rtp_timestamp) {
    209   DCHECK(transport_sender_);
    210   uint32 packet_type_flags = transport::kRtcpSr;
    211   uint32 current_ntp_seconds = 0;
    212   uint32 current_ntp_fractions = 0;
    213   ConvertTimeTicksToNtp(current_time, &current_ntp_seconds,
    214                         &current_ntp_fractions);
    215   SaveLastSentNtpTime(current_time, current_ntp_seconds,
    216                       current_ntp_fractions);
    217 
    218   transport::RtcpDlrrReportBlock dlrr;
    219   if (!time_last_report_received_.is_null()) {
    220     packet_type_flags |= transport::kRtcpDlrr;
    221     dlrr.last_rr = last_report_truncated_ntp_;
    222     uint32 delay_seconds = 0;
    223     uint32 delay_fraction = 0;
    224     base::TimeDelta delta = current_time - time_last_report_received_;
    225     ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds,
    226                            &delay_fraction);
    227 
    228     dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction);
    229   }
    230 
    231   transport_sender_->SendRtcpFromRtpSender(
    232       packet_type_flags, current_ntp_seconds, current_ntp_fractions,
    233       current_time_as_rtp_timestamp, dlrr, local_ssrc_, c_name_);
    234   UpdateNextTimeToSendRtcp();
    235 }
    236 
    237 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) {
    238   last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction);
    239 
    240   const base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    241   time_last_report_received_ = now;
    242 
    243   // TODO(miu): This clock offset calculation does not account for packet
    244   // transit time over the network.  End2EndTest.EvilNetwork confirms that this
    245   // contributes a very significant source of error here.  Fix this along with
    246   // the RTT clean-up.
    247   const base::TimeDelta measured_offset =
    248       now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction);
    249   local_clock_ahead_by_.Update(now, measured_offset);
    250   if (measured_offset < local_clock_ahead_by_.Current()) {
    251     // Logically, the minimum offset between the clocks has to be the correct
    252     // one.  For example, the time it took to transmit the current report may
    253     // have been lower than usual, and so some of the error introduced by the
    254     // transmission time can be eliminated.
    255     local_clock_ahead_by_.Reset(now, measured_offset);
    256   }
    257   VLOG(1) << "Local clock is ahead of the remote clock by: "
    258           << "measured=" << measured_offset.InMicroseconds() << " usec, "
    259           << "filtered=" << local_clock_ahead_by_.Current().InMicroseconds()
    260           << " usec.";
    261 }
    262 
    263 void Rtcp::OnReceivedLipSyncInfo(uint32 rtp_timestamp, uint32 ntp_seconds,
    264                                  uint32 ntp_fraction) {
    265   if (ntp_seconds == 0) {
    266     NOTREACHED();
    267     return;
    268   }
    269   lip_sync_rtp_timestamp_ = rtp_timestamp;
    270   lip_sync_ntp_timestamp_ =
    271       (static_cast<uint64>(ntp_seconds) << 32) | ntp_fraction;
    272 }
    273 
    274 bool Rtcp::GetLatestLipSyncTimes(uint32* rtp_timestamp,
    275                                  base::TimeTicks* reference_time) const {
    276   if (!lip_sync_ntp_timestamp_)
    277     return false;
    278 
    279   const base::TimeTicks local_reference_time =
    280       ConvertNtpToTimeTicks(static_cast<uint32>(lip_sync_ntp_timestamp_ >> 32),
    281                             static_cast<uint32>(lip_sync_ntp_timestamp_)) +
    282       local_clock_ahead_by_.Current();
    283 
    284   // Sanity-check: Getting regular lip sync updates?
    285   DCHECK((cast_environment_->Clock()->NowTicks() - local_reference_time) <
    286              base::TimeDelta::FromMinutes(1));
    287 
    288   *rtp_timestamp = lip_sync_rtp_timestamp_;
    289   *reference_time = local_reference_time;
    290   return true;
    291 }
    292 
    293 void Rtcp::OnReceivedSendReportRequest() {
    294   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    295 
    296   // Trigger a new RTCP report at next timer.
    297   next_time_to_send_rtcp_ = now;
    298 }
    299 
    300 void Rtcp::SetCastReceiverEventHistorySize(size_t size) {
    301   rtcp_receiver_->SetCastReceiverEventHistorySize(size);
    302 }
    303 
    304 void Rtcp::SetTargetDelay(base::TimeDelta target_delay) {
    305   DCHECK(target_delay.InMilliseconds() < kMaxDelay);
    306   target_delay_ms_ = static_cast<uint16>(target_delay.InMilliseconds());
    307 }
    308 
    309 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc,
    310                                           uint32 last_report,
    311                                           uint32 delay_since_last_report) {
    312   RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report);
    313   if (it == last_reports_sent_map_.end()) {
    314     return;  // Feedback on another report.
    315   }
    316 
    317   base::TimeDelta sender_delay =
    318       cast_environment_->Clock()->NowTicks() - it->second;
    319   UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report));
    320 }
    321 
    322 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now,
    323                                uint32 last_ntp_seconds,
    324                                uint32 last_ntp_fraction) {
    325   // Make sure |now| is always greater than the last element in
    326   // |last_reports_sent_queue_|.
    327   if (!last_reports_sent_queue_.empty())
    328     DCHECK(now >= last_reports_sent_queue_.back().second);
    329 
    330   uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction);
    331   last_reports_sent_map_[last_report] = now;
    332   last_reports_sent_queue_.push(std::make_pair(last_report, now));
    333 
    334   base::TimeTicks timeout = now - base::TimeDelta::FromMilliseconds(kMaxRttMs);
    335 
    336   // Cleanup old statistics older than |timeout|.
    337   while (!last_reports_sent_queue_.empty()) {
    338     RtcpSendTimePair oldest_report = last_reports_sent_queue_.front();
    339     if (oldest_report.second < timeout) {
    340       last_reports_sent_map_.erase(oldest_report.first);
    341       last_reports_sent_queue_.pop();
    342     } else {
    343       break;
    344     }
    345   }
    346 }
    347 
    348 void Rtcp::UpdateRtt(const base::TimeDelta& sender_delay,
    349                      const base::TimeDelta& receiver_delay) {
    350   base::TimeDelta rtt = sender_delay - receiver_delay;
    351   // TODO(miu): Find out why this must be >= 1 ms, and remove the fudge if it's
    352   // bogus.
    353   rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1));
    354   rtt_ = rtt;
    355   min_rtt_ = std::min(min_rtt_, rtt);
    356   max_rtt_ = std::max(max_rtt_, rtt);
    357 
    358   // TODO(miu): Replace "average for all time" with an EWMA, or suitable
    359   // "average over recent past" mechanism.
    360   if (number_of_rtt_in_avg_ != 0) {
    361     const double ac = static_cast<double>(number_of_rtt_in_avg_);
    362     avg_rtt_ms_ = ((ac / (ac + 1.0)) * avg_rtt_ms_) +
    363                   ((1.0 / (ac + 1.0)) * rtt.InMillisecondsF());
    364   } else {
    365     avg_rtt_ms_ = rtt.InMillisecondsF();
    366   }
    367   number_of_rtt_in_avg_++;
    368 }
    369 
    370 bool Rtcp::Rtt(base::TimeDelta* rtt, base::TimeDelta* avg_rtt,
    371                base::TimeDelta* min_rtt, base::TimeDelta* max_rtt) const {
    372   DCHECK(rtt) << "Invalid argument";
    373   DCHECK(avg_rtt) << "Invalid argument";
    374   DCHECK(min_rtt) << "Invalid argument";
    375   DCHECK(max_rtt) << "Invalid argument";
    376 
    377   if (number_of_rtt_in_avg_ == 0) return false;
    378 
    379   *rtt = rtt_;
    380   *avg_rtt = base::TimeDelta::FromMillisecondsD(avg_rtt_ms_);
    381   *min_rtt = min_rtt_;
    382   *max_rtt = max_rtt_;
    383   return true;
    384 }
    385 
    386 void Rtcp::UpdateNextTimeToSendRtcp() {
    387   int random = base::RandInt(0, 999);
    388   base::TimeDelta time_to_next =
    389       (rtcp_interval_ / 2) + (rtcp_interval_ * random / 1000);
    390 
    391   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    392   next_time_to_send_rtcp_ = now + time_to_next;
    393 }
    394 
    395 void Rtcp::OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) {
    396   // Add received log messages into our log system.
    397   RtcpReceiverLogMessage::const_iterator it = receiver_log.begin();
    398   for (; it != receiver_log.end(); ++it) {
    399     uint32 rtp_timestamp = it->rtp_timestamp_;
    400 
    401     RtcpReceiverEventLogMessages::const_iterator event_it =
    402         it->event_log_messages_.begin();
    403     for (; event_it != it->event_log_messages_.end(); ++event_it) {
    404       switch (event_it->type) {
    405         case PACKET_RECEIVED:
    406           cast_environment_->Logging()->InsertPacketEvent(
    407               event_it->event_timestamp, event_it->type,
    408               event_media_type_, rtp_timestamp,
    409               kFrameIdUnknown, event_it->packet_id, 0, 0);
    410           break;
    411         case FRAME_ACK_SENT:
    412         case FRAME_DECODED:
    413           cast_environment_->Logging()->InsertFrameEvent(
    414               event_it->event_timestamp, event_it->type, event_media_type_,
    415               rtp_timestamp, kFrameIdUnknown);
    416           break;
    417         case FRAME_PLAYOUT:
    418           cast_environment_->Logging()->InsertFrameEventWithDelay(
    419               event_it->event_timestamp, event_it->type, event_media_type_,
    420               rtp_timestamp, kFrameIdUnknown, event_it->delay_delta);
    421           break;
    422         default:
    423           VLOG(2) << "Received log message via RTCP that we did not expect: "
    424                   << static_cast<int>(event_it->type);
    425           break;
    426       }
    427     }
    428   }
    429 }
    430 
    431 }  // namespace cast
    432 }  // namespace media
    433