Home | History | Annotate | Download | only in framer
      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/framer/cast_message_builder.h"
      6 
      7 #include "media/cast/cast_defines.h"
      8 
      9 namespace media {
     10 namespace cast {
     11 
     12 CastMessageBuilder::CastMessageBuilder(
     13     base::TickClock* clock,
     14     RtpPayloadFeedback* incoming_payload_feedback,
     15     FrameIdMap* frame_id_map,
     16     uint32 media_ssrc,
     17     bool decoder_faster_than_max_frame_rate,
     18     int max_unacked_frames)
     19     : clock_(clock),
     20       cast_feedback_(incoming_payload_feedback),
     21       frame_id_map_(frame_id_map),
     22       media_ssrc_(media_ssrc),
     23       decoder_faster_than_max_frame_rate_(decoder_faster_than_max_frame_rate),
     24       max_unacked_frames_(max_unacked_frames),
     25       cast_msg_(media_ssrc),
     26       waiting_for_key_frame_(true),
     27       slowing_down_ack_(false),
     28       acked_last_frame_(true),
     29       last_acked_frame_id_(kStartFrameId) {
     30   cast_msg_.ack_frame_id_ = kStartFrameId;
     31 }
     32 
     33 CastMessageBuilder::~CastMessageBuilder() {}
     34 
     35 void CastMessageBuilder::CompleteFrameReceived(uint32 frame_id,
     36                                                bool is_key_frame) {
     37   if (last_update_time_.is_null()) {
     38     // Our first update.
     39     last_update_time_ = clock_->NowTicks();
     40   }
     41   if (waiting_for_key_frame_) {
     42     if (!is_key_frame) {
     43       // Ignore that we have received this complete frame since we are
     44       // waiting on a key frame.
     45       return;
     46     }
     47     waiting_for_key_frame_ = false;
     48     cast_msg_.missing_frames_and_packets_.clear();
     49     cast_msg_.ack_frame_id_ = frame_id;
     50     last_update_time_ = clock_->NowTicks();
     51     // We might have other complete frames waiting after we receive the last
     52     // packet in the key-frame.
     53     UpdateAckMessage();
     54   } else {
     55     if (!UpdateAckMessage()) return;
     56 
     57     BuildPacketList();
     58   }
     59   // Send cast message.
     60   VLOG(1) << "Send cast message Ack:" << static_cast<int>(frame_id);
     61   cast_feedback_->CastFeedback(cast_msg_);
     62 }
     63 
     64 bool CastMessageBuilder::UpdateAckMessage() {
     65   if (!decoder_faster_than_max_frame_rate_) {
     66     int complete_frame_count = frame_id_map_->NumberOfCompleteFrames();
     67     if (complete_frame_count > max_unacked_frames_) {
     68       // We have too many frames pending in our framer; slow down ACK.
     69       slowing_down_ack_ = true;
     70     } else if (complete_frame_count <= 1) {
     71       // We are down to one or less frames in our framer; ACK normally.
     72       slowing_down_ack_ = false;
     73     }
     74   }
     75   if (slowing_down_ack_) {
     76     // We are slowing down acknowledgment by acknowledging every other frame.
     77     if (acked_last_frame_) {
     78       acked_last_frame_ = false;
     79     } else {
     80       acked_last_frame_ = true;
     81       last_acked_frame_id_++;
     82       // Note: frame skipping and slowdown ACK is not supported at the same
     83       // time; and it's not needed since we can skip frames to catch up.
     84     }
     85   } else {
     86     uint32 frame_id = frame_id_map_->LastContinuousFrame();
     87 
     88     // Is it a new frame?
     89     if (last_acked_frame_id_ == frame_id) return false;
     90 
     91     last_acked_frame_id_ = frame_id;
     92     acked_last_frame_ = true;
     93   }
     94   cast_msg_.ack_frame_id_ = last_acked_frame_id_;
     95   cast_msg_.missing_frames_and_packets_.clear();
     96   last_update_time_ = clock_->NowTicks();
     97   return true;
     98 }
     99 
    100 bool CastMessageBuilder::TimeToSendNextCastMessage(
    101     base::TimeTicks* time_to_send) {
    102   // We haven't received any packets.
    103   if (last_update_time_.is_null() && frame_id_map_->Empty()) return false;
    104 
    105   *time_to_send = last_update_time_ +
    106       base::TimeDelta::FromMilliseconds(kCastMessageUpdateIntervalMs);
    107   return true;
    108 }
    109 
    110 void CastMessageBuilder::UpdateCastMessage() {
    111   RtcpCastMessage message(media_ssrc_);
    112   if (!UpdateCastMessageInternal(&message)) return;
    113 
    114   // Send cast message.
    115   cast_feedback_->CastFeedback(message);
    116 }
    117 
    118 void CastMessageBuilder::Reset() {
    119   waiting_for_key_frame_ = true;
    120   cast_msg_.ack_frame_id_ = kStartFrameId;
    121   cast_msg_.missing_frames_and_packets_.clear();
    122   time_last_nacked_map_.clear();
    123 }
    124 
    125 bool CastMessageBuilder::UpdateCastMessageInternal(RtcpCastMessage* message) {
    126   if (last_update_time_.is_null()) {
    127     if (!frame_id_map_->Empty()) {
    128       // We have received packets.
    129       last_update_time_ = clock_->NowTicks();
    130     }
    131     return false;
    132   }
    133   // Is it time to update the cast message?
    134   base::TimeTicks now = clock_->NowTicks();
    135   if (now - last_update_time_ <
    136       base::TimeDelta::FromMilliseconds(kCastMessageUpdateIntervalMs)) {
    137     return false;
    138   }
    139   last_update_time_ = now;
    140 
    141   UpdateAckMessage();  // Needed to cover when a frame is skipped.
    142   BuildPacketList();
    143   *message = cast_msg_;
    144   return true;
    145 }
    146 
    147 void CastMessageBuilder::BuildPacketList() {
    148   base::TimeTicks now = clock_->NowTicks();
    149 
    150   // Clear message NACK list.
    151   cast_msg_.missing_frames_and_packets_.clear();
    152 
    153   // Are we missing packets?
    154   if (frame_id_map_->Empty()) return;
    155 
    156   uint32 newest_frame_id = frame_id_map_->NewestFrameId();
    157   uint32 next_expected_frame_id = cast_msg_.ack_frame_id_ + 1;
    158 
    159   // Iterate over all frames.
    160   for (; !IsNewerFrameId(next_expected_frame_id, newest_frame_id);
    161        ++next_expected_frame_id) {
    162     TimeLastNackMap::iterator it =
    163         time_last_nacked_map_.find(next_expected_frame_id);
    164     if (it != time_last_nacked_map_.end()) {
    165       // We have sent a NACK in this frame before, make sure enough time have
    166       // passed.
    167       if (now - it->second <
    168           base::TimeDelta::FromMilliseconds(kNackRepeatIntervalMs)) {
    169         continue;
    170       }
    171     }
    172 
    173     PacketIdSet missing;
    174     if (frame_id_map_->FrameExists(next_expected_frame_id)) {
    175       bool last_frame = (newest_frame_id == next_expected_frame_id);
    176       frame_id_map_->GetMissingPackets(next_expected_frame_id, last_frame,
    177                                        &missing);
    178       if (!missing.empty()) {
    179         time_last_nacked_map_[next_expected_frame_id] = now;
    180         cast_msg_.missing_frames_and_packets_.insert(
    181             std::make_pair(next_expected_frame_id, missing));
    182       }
    183     } else {
    184       time_last_nacked_map_[next_expected_frame_id] = now;
    185       missing.insert(kRtcpCastAllPacketsLost);
    186       cast_msg_.missing_frames_and_packets_[next_expected_frame_id] = missing;
    187     }
    188   }
    189 }
    190 
    191 }  //  namespace cast
    192 }  //  namespace media
    193