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/rand_util.h"
      8 #include "media/cast/cast_config.h"
      9 #include "media/cast/cast_defines.h"
     10 #include "media/cast/cast_environment.h"
     11 #include "media/cast/rtcp/rtcp_defines.h"
     12 #include "media/cast/rtcp/rtcp_receiver.h"
     13 #include "media/cast/rtcp/rtcp_sender.h"
     14 #include "media/cast/rtcp/rtcp_utility.h"
     15 #include "net/base/big_endian.h"
     16 
     17 namespace media {
     18 namespace cast {
     19 
     20 static const int kMaxRttMs = 10000;  // 10 seconds.
     21 
     22 // Time limit for received RTCP messages when we stop using it for lip-sync.
     23 static const int64 kMaxDiffSinceReceivedRtcpMs = 100000;  // 100 seconds.
     24 
     25 class LocalRtcpRttFeedback : public RtcpRttFeedback {
     26  public:
     27   explicit LocalRtcpRttFeedback(Rtcp* rtcp)
     28       : rtcp_(rtcp) {
     29   }
     30 
     31   virtual void OnReceivedDelaySinceLastReport(
     32       uint32 receivers_ssrc,
     33       uint32 last_report,
     34       uint32 delay_since_last_report) OVERRIDE {
     35     rtcp_->OnReceivedDelaySinceLastReport(receivers_ssrc,
     36                                           last_report,
     37                                           delay_since_last_report);
     38   }
     39 
     40  private:
     41   Rtcp* rtcp_;
     42 };
     43 
     44 RtcpCastMessage::RtcpCastMessage(uint32 media_ssrc)
     45     : media_ssrc_(media_ssrc) {}
     46 
     47 RtcpCastMessage::~RtcpCastMessage() {}
     48 
     49 RtcpNackMessage::RtcpNackMessage() {}
     50 RtcpNackMessage::~RtcpNackMessage() {}
     51 
     52 RtcpRembMessage::RtcpRembMessage() {}
     53 RtcpRembMessage::~RtcpRembMessage() {}
     54 
     55 RtcpReceiverFrameLogMessage::RtcpReceiverFrameLogMessage(uint32 timestamp)
     56     : rtp_timestamp_(timestamp) {}
     57 
     58 RtcpReceiverFrameLogMessage::~RtcpReceiverFrameLogMessage() {}
     59 
     60 class LocalRtcpReceiverFeedback : public RtcpReceiverFeedback {
     61  public:
     62   LocalRtcpReceiverFeedback(Rtcp* rtcp,
     63                            scoped_refptr<CastEnvironment> cast_environment)
     64       : rtcp_(rtcp), cast_environment_(cast_environment) {
     65   }
     66 
     67   virtual void OnReceivedSenderReport(
     68       const RtcpSenderInfo& remote_sender_info) OVERRIDE {
     69     rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds,
     70                          remote_sender_info.ntp_fraction);
     71     if (remote_sender_info.send_packet_count != 0) {
     72       rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp,
     73                                    remote_sender_info.ntp_seconds,
     74                                    remote_sender_info.ntp_fraction);
     75     }
     76   }
     77 
     78   virtual void OnReceiverReferenceTimeReport(
     79       const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE {
     80     rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds,
     81                          remote_time_report.ntp_fraction);
     82   }
     83 
     84   virtual void OnReceivedSendReportRequest() OVERRIDE {
     85     rtcp_->OnReceivedSendReportRequest();
     86   }
     87 
     88   virtual void OnReceivedReceiverLog(
     89       const RtcpReceiverLogMessage& receiver_log) OVERRIDE {
     90     // Add received log messages into our log system.
     91     RtcpReceiverLogMessage::const_iterator it = receiver_log.begin();
     92 
     93     for (; it != receiver_log.end(); ++it) {
     94       uint32 rtp_timestamp = it->rtp_timestamp_;
     95 
     96       RtcpReceiverEventLogMessages::const_iterator event_it =
     97           it->event_log_messages_.begin();
     98       for (; event_it != it->event_log_messages_.end(); ++event_it) {
     99         // TODO(pwestin): we need to send in the event_it->event_timestamp to
    100         // the log system too.
    101         switch (event_it->type) {
    102           case kPacketReceived:
    103             cast_environment_->Logging()->InsertPacketEvent(kPacketReceived,
    104                 rtp_timestamp, kFrameIdUnknown, event_it->packet_id, 0, 0);
    105             break;
    106           case kAckSent:
    107           case kAudioFrameDecoded:
    108           case kVideoFrameDecoded:
    109             cast_environment_->Logging()->InsertFrameEvent(event_it->type,
    110                 rtp_timestamp, kFrameIdUnknown);
    111             break;
    112           case kAudioPlayoutDelay:
    113           case kVideoRenderDelay:
    114             cast_environment_->Logging()->InsertFrameEventWithDelay(
    115                 event_it->type, rtp_timestamp, kFrameIdUnknown,
    116                 event_it->delay_delta);
    117             break;
    118           default:
    119             VLOG(2) << "Received log message via RTCP that we did not expect: "
    120                     << static_cast<int>(event_it->type);
    121             break;
    122         }
    123       }
    124     }
    125   }
    126 
    127   virtual void OnReceivedSenderLog(
    128       const RtcpSenderLogMessage& sender_log)  OVERRIDE {
    129     RtcpSenderLogMessage::const_iterator it = sender_log.begin();
    130 
    131     for (; it != sender_log.end(); ++it) {
    132       uint32 rtp_timestamp = it->rtp_timestamp;
    133       CastLoggingEvent log_event = kUnknown;
    134 
    135       // These events are provided to know the status of frames that never
    136       // reached the receiver. The timing information for these events are not
    137       // relevant and is not sent over the wire.
    138       switch (it->frame_status) {
    139         case kRtcpSenderFrameStatusDroppedByFlowControl:
    140           // A frame that have been dropped by the flow control would have
    141           // kVideoFrameCaptured as its last event in the log.
    142           log_event = kVideoFrameCaptured;
    143           break;
    144         case kRtcpSenderFrameStatusDroppedByEncoder:
    145           // A frame that have been dropped by the encoder would have
    146           // kVideoFrameSentToEncoder as its last event in the log.
    147           log_event = kVideoFrameSentToEncoder;
    148           break;
    149         case kRtcpSenderFrameStatusSentToNetwork:
    150           // A frame that have be encoded is always sent to the network. We
    151           // do not add a new log entry for this.
    152           log_event = kVideoFrameEncoded;
    153           break;
    154         default:
    155           continue;
    156       }
    157       // TODO(pwestin): how do we handle the truncated rtp_timestamp?
    158       // Add received log messages into our log system.
    159       cast_environment_->Logging()->InsertFrameEvent(log_event, rtp_timestamp,
    160           kFrameIdUnknown);
    161     }
    162   }
    163 
    164  private:
    165   Rtcp* rtcp_;
    166   scoped_refptr<CastEnvironment> cast_environment_;
    167 };
    168 
    169 Rtcp::Rtcp(scoped_refptr<CastEnvironment> cast_environment,
    170            RtcpSenderFeedback* sender_feedback,
    171            PacedPacketSender* paced_packet_sender,
    172            RtpSenderStatistics* rtp_sender_statistics,
    173            RtpReceiverStatistics* rtp_receiver_statistics,
    174            RtcpMode rtcp_mode,
    175            const base::TimeDelta& rtcp_interval,
    176            uint32 local_ssrc,
    177            uint32 remote_ssrc,
    178            const std::string& c_name)
    179     : rtcp_interval_(rtcp_interval),
    180       rtcp_mode_(rtcp_mode),
    181       local_ssrc_(local_ssrc),
    182       remote_ssrc_(remote_ssrc),
    183       rtp_sender_statistics_(rtp_sender_statistics),
    184       rtp_receiver_statistics_(rtp_receiver_statistics),
    185       receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)),
    186       rtt_feedback_(new LocalRtcpRttFeedback(this)),
    187       rtcp_sender_(new RtcpSender(cast_environment, paced_packet_sender,
    188                                   local_ssrc, c_name)),
    189       last_report_received_(0),
    190       last_received_rtp_timestamp_(0),
    191       last_received_ntp_seconds_(0),
    192       last_received_ntp_fraction_(0),
    193       min_rtt_(base::TimeDelta::FromMilliseconds(kMaxRttMs)),
    194       number_of_rtt_in_avg_(0),
    195       cast_environment_(cast_environment) {
    196   rtcp_receiver_.reset(new RtcpReceiver(cast_environment,
    197                                         sender_feedback,
    198                                         receiver_feedback_.get(),
    199                                         rtt_feedback_.get(),
    200                                         local_ssrc));
    201   rtcp_receiver_->SetRemoteSSRC(remote_ssrc);
    202 }
    203 
    204 Rtcp::~Rtcp() {}
    205 
    206 // static
    207 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) {
    208   DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet";
    209   if (length < kMinLengthOfRtcp) return false;
    210 
    211   uint8 packet_type = packet[1];
    212   if (packet_type >= kPacketTypeLow && packet_type <= kPacketTypeHigh) {
    213     return true;
    214   }
    215   return false;
    216 }
    217 
    218 // static
    219 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) {
    220   DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet";
    221   uint32 ssrc_of_sender;
    222   net::BigEndianReader big_endian_reader(rtcp_buffer, length);
    223   big_endian_reader.Skip(4);  // Skip header
    224   big_endian_reader.ReadU32(&ssrc_of_sender);
    225   return ssrc_of_sender;
    226 }
    227 
    228 base::TimeTicks Rtcp::TimeToSendNextRtcpReport() {
    229   if (next_time_to_send_rtcp_.is_null()) {
    230     UpdateNextTimeToSendRtcp();
    231   }
    232   return next_time_to_send_rtcp_;
    233 }
    234 
    235 void Rtcp::IncomingRtcpPacket(const uint8* rtcp_buffer, size_t length) {
    236   RtcpParser rtcp_parser(rtcp_buffer, length);
    237   if (!rtcp_parser.IsValid()) {
    238     // Silently ignore packet.
    239     DLOG(ERROR) << "Received invalid RTCP packet";
    240     return;
    241   }
    242   rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser);
    243 }
    244 
    245 void Rtcp::SendRtcpFromRtpReceiver(const RtcpCastMessage* cast_message,
    246                                    RtcpReceiverLogMessage* receiver_log) {
    247   uint32 packet_type_flags = 0;
    248 
    249   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    250   RtcpReportBlock report_block;
    251   RtcpReceiverReferenceTimeReport rrtr;
    252 
    253   if (cast_message) {
    254     packet_type_flags |= RtcpSender::kRtcpCast;
    255     cast_environment_->Logging()->InsertGenericEvent(kAckSent,
    256         cast_message->ack_frame_id_);
    257   }
    258   if (receiver_log) {
    259     packet_type_flags |= RtcpSender::kRtcpReceiverLog;
    260   }
    261   if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) {
    262     packet_type_flags |= RtcpSender::kRtcpRr;
    263 
    264     report_block.remote_ssrc = 0;  // Not needed to set send side.
    265     report_block.media_ssrc = remote_ssrc_;  // SSRC of the RTP packet sender.
    266     if (rtp_receiver_statistics_) {
    267       rtp_receiver_statistics_->GetStatistics(
    268           &report_block.fraction_lost,
    269           &report_block.cumulative_lost,
    270           &report_block.extended_high_sequence_number,
    271           &report_block.jitter);
    272       cast_environment_->Logging()->InsertGenericEvent(kJitterMs,
    273           report_block.jitter);
    274       cast_environment_->Logging()->InsertGenericEvent(kPacketLoss,
    275           report_block.fraction_lost);
    276 
    277     }
    278 
    279     report_block.last_sr = last_report_received_;
    280     if (!time_last_report_received_.is_null()) {
    281       uint32 delay_seconds = 0;
    282       uint32 delay_fraction = 0;
    283       base::TimeDelta delta = now - time_last_report_received_;
    284       ConvertTimeToFractions(delta.InMicroseconds(),
    285                              &delay_seconds,
    286                              &delay_fraction);
    287       report_block.delay_since_last_sr =
    288           ConvertToNtpDiff(delay_seconds, delay_fraction);
    289     } else {
    290       report_block.delay_since_last_sr = 0;
    291     }
    292 
    293     packet_type_flags |= RtcpSender::kRtcpRrtr;
    294     ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction);
    295     SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction);
    296     UpdateNextTimeToSendRtcp();
    297   }
    298   rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags,
    299                                         &report_block,
    300                                         &rrtr,
    301                                         cast_message,
    302                                         receiver_log);
    303 }
    304 
    305 void Rtcp::SendRtcpFromRtpSender(
    306     RtcpSenderLogMessage* sender_log_message) {
    307   uint32 packet_type_flags = RtcpSender::kRtcpSr;
    308   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    309 
    310   if (sender_log_message) {
    311     packet_type_flags |= RtcpSender::kRtcpSenderLog;
    312   }
    313 
    314   RtcpSenderInfo sender_info;
    315   if (rtp_sender_statistics_) {
    316     rtp_sender_statistics_->GetStatistics(now, &sender_info);
    317   } else {
    318     memset(&sender_info, 0, sizeof(sender_info));
    319   }
    320   SaveLastSentNtpTime(now, sender_info.ntp_seconds, sender_info.ntp_fraction);
    321 
    322   RtcpDlrrReportBlock dlrr;
    323   if (!time_last_report_received_.is_null()) {
    324     packet_type_flags |= RtcpSender::kRtcpDlrr;
    325     dlrr.last_rr = last_report_received_;
    326     uint32 delay_seconds = 0;
    327     uint32 delay_fraction = 0;
    328     base::TimeDelta delta = now - time_last_report_received_;
    329     ConvertTimeToFractions(delta.InMicroseconds(),
    330                            &delay_seconds,
    331                            &delay_fraction);
    332 
    333     dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction);
    334   }
    335 
    336   rtcp_sender_->SendRtcpFromRtpSender(packet_type_flags,
    337                                       &sender_info,
    338                                       &dlrr,
    339                                       sender_log_message);
    340   UpdateNextTimeToSendRtcp();
    341 }
    342 
    343 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) {
    344   last_report_received_ = (ntp_seconds << 16) + (ntp_fraction >> 16);
    345 
    346   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    347   time_last_report_received_ = now;
    348 }
    349 
    350 void Rtcp::OnReceivedLipSyncInfo(uint32 rtp_timestamp,
    351                                  uint32 ntp_seconds,
    352                                  uint32 ntp_fraction) {
    353   last_received_rtp_timestamp_ = rtp_timestamp;
    354   last_received_ntp_seconds_ = ntp_seconds;
    355   last_received_ntp_fraction_ = ntp_fraction;
    356 }
    357 
    358 void Rtcp::OnReceivedSendReportRequest() {
    359   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    360 
    361   // Trigger a new RTCP report at next timer.
    362   next_time_to_send_rtcp_ = now;
    363 }
    364 
    365 bool Rtcp::RtpTimestampInSenderTime(int frequency, uint32 rtp_timestamp,
    366       base::TimeTicks* rtp_timestamp_in_ticks) const {
    367   if (last_received_ntp_seconds_ == 0)  return false;
    368 
    369   int wrap = CheckForWrapAround(rtp_timestamp, last_received_rtp_timestamp_);
    370   int64 rtp_timestamp_int64 = rtp_timestamp;
    371   int64 last_received_rtp_timestamp_int64 = last_received_rtp_timestamp_;
    372 
    373   if (wrap == 1) {
    374     rtp_timestamp_int64 += (1LL << 32);
    375   } else if (wrap == -1) {
    376     last_received_rtp_timestamp_int64 += (1LL << 32);
    377   }
    378   // Time since the last RTCP message.
    379   // Note that this can be negative since we can compare a rtp timestamp from
    380   // a frame older than the last received RTCP message.
    381   int64 rtp_timestamp_diff =
    382       rtp_timestamp_int64 - last_received_rtp_timestamp_int64;
    383 
    384   int frequency_khz = frequency / 1000;
    385   int64 rtp_time_diff_ms = rtp_timestamp_diff / frequency_khz;
    386 
    387   // Sanity check.
    388   if (abs(rtp_time_diff_ms) > kMaxDiffSinceReceivedRtcpMs)  return false;
    389 
    390   *rtp_timestamp_in_ticks = ConvertNtpToTimeTicks(last_received_ntp_seconds_,
    391       last_received_ntp_fraction_) +
    392       base::TimeDelta::FromMilliseconds(rtp_time_diff_ms);
    393   return true;
    394 }
    395 
    396 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc,
    397                                           uint32 last_report,
    398                                           uint32 delay_since_last_report) {
    399   RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report);
    400   if (it == last_reports_sent_map_.end()) {
    401     return;  // Feedback on another report.
    402   }
    403 
    404   base::TimeDelta sender_delay = cast_environment_->Clock()->NowTicks()
    405       - it->second;
    406   UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report));
    407 }
    408 
    409 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now,
    410                                uint32 last_ntp_seconds,
    411                                uint32 last_ntp_fraction) {
    412   // Make sure |now| is always greater than the last element in
    413   // |last_reports_sent_queue_|.
    414   if (!last_reports_sent_queue_.empty()) {
    415     DCHECK(now >= last_reports_sent_queue_.back().second);
    416   }
    417 
    418   uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction);
    419   last_reports_sent_map_[last_report] = now;
    420   last_reports_sent_queue_.push(std::make_pair(last_report, now));
    421 
    422   base::TimeTicks timeout = now - base::TimeDelta::FromMilliseconds(kMaxRttMs);
    423 
    424   // Cleanup old statistics older than |timeout|.
    425   while (!last_reports_sent_queue_.empty()) {
    426     RtcpSendTimePair oldest_report = last_reports_sent_queue_.front();
    427     if (oldest_report.second < timeout) {
    428       last_reports_sent_map_.erase(oldest_report.first);
    429       last_reports_sent_queue_.pop();
    430     } else {
    431       break;
    432     }
    433   }
    434 }
    435 
    436 void Rtcp::UpdateRtt(const base::TimeDelta& sender_delay,
    437                      const base::TimeDelta& receiver_delay) {
    438   base::TimeDelta rtt = sender_delay - receiver_delay;
    439   rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1));
    440   rtt_ = rtt;
    441   min_rtt_ = std::min(min_rtt_, rtt);
    442   max_rtt_ = std::max(max_rtt_, rtt);
    443 
    444   if (number_of_rtt_in_avg_ != 0) {
    445     float ac = static_cast<float>(number_of_rtt_in_avg_);
    446     avg_rtt_ms_= ((ac / (ac + 1.0)) * avg_rtt_ms_) +
    447         ((1.0 / (ac + 1.0)) * rtt.InMilliseconds());
    448   } else {
    449     avg_rtt_ms_ = rtt.InMilliseconds();
    450   }
    451   number_of_rtt_in_avg_++;
    452 }
    453 
    454 bool Rtcp::Rtt(base::TimeDelta* rtt,
    455                base::TimeDelta* avg_rtt,
    456                base::TimeDelta* min_rtt,
    457                base::TimeDelta* max_rtt) const {
    458   DCHECK(rtt) << "Invalid argument";
    459   DCHECK(avg_rtt) << "Invalid argument";
    460   DCHECK(min_rtt) << "Invalid argument";
    461   DCHECK(max_rtt) << "Invalid argument";
    462 
    463   if (number_of_rtt_in_avg_ == 0) return false;
    464   cast_environment_->Logging()->InsertGenericEvent(kRttMs,
    465                                                    rtt->InMilliseconds());
    466 
    467   *rtt = rtt_;
    468   *avg_rtt = base::TimeDelta::FromMilliseconds(avg_rtt_ms_);
    469   *min_rtt = min_rtt_;
    470   *max_rtt = max_rtt_;
    471   return true;
    472 }
    473 
    474 int Rtcp::CheckForWrapAround(uint32 new_timestamp,
    475                              uint32 old_timestamp) const {
    476   if (new_timestamp < old_timestamp) {
    477     // This difference should be less than -2^31 if we have had a wrap around
    478     // (e.g. |new_timestamp| = 1, |rtcp_rtp_timestamp| = 2^32 - 1). Since it is
    479     // cast to a int32_t, it should be positive.
    480     if (static_cast<int32>(new_timestamp - old_timestamp) > 0) {
    481       return 1;  // Forward wrap around.
    482     }
    483   } else if (static_cast<int32>(old_timestamp - new_timestamp) > 0) {
    484     // This difference should be less than -2^31 if we have had a backward wrap
    485     // around. Since it is cast to a int32, it should be positive.
    486     return -1;
    487   }
    488   return 0;
    489 }
    490 
    491 void Rtcp::UpdateNextTimeToSendRtcp() {
    492   int random = base::RandInt(0, 999);
    493   base::TimeDelta time_to_next = (rtcp_interval_ / 2) +
    494       (rtcp_interval_ * random / 1000);
    495 
    496   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
    497   next_time_to_send_rtcp_ = now + time_to_next;
    498 }
    499 
    500 }  // namespace cast
    501 }  // namespace media
    502