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