| OLD | NEW |
| (Empty) |
| 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/frame_id_map.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "media/cast/rtp_receiver/rtp_receiver_defines.h" | |
| 9 | |
| 10 namespace media { | |
| 11 namespace cast { | |
| 12 | |
| 13 FrameInfo::FrameInfo(uint32 frame_id, | |
| 14 uint32 referenced_frame_id, | |
| 15 uint16 max_packet_id, | |
| 16 bool key_frame) | |
| 17 : is_key_frame_(key_frame), | |
| 18 frame_id_(frame_id), | |
| 19 referenced_frame_id_(referenced_frame_id), | |
| 20 max_received_packet_id_(0) { | |
| 21 // Create the set with all packets missing. | |
| 22 for (uint16 i = 0; i <= max_packet_id; i++) { | |
| 23 missing_packets_.insert(i); | |
| 24 } | |
| 25 } | |
| 26 | |
| 27 FrameInfo::~FrameInfo() {} | |
| 28 | |
| 29 PacketType FrameInfo::InsertPacket(uint16 packet_id) { | |
| 30 if (missing_packets_.find(packet_id) == missing_packets_.end()) { | |
| 31 return kDuplicatePacket; | |
| 32 } | |
| 33 // Update the last received packet id. | |
| 34 if (IsNewerPacketId(packet_id, max_received_packet_id_)) { | |
| 35 max_received_packet_id_ = packet_id; | |
| 36 } | |
| 37 missing_packets_.erase(packet_id); | |
| 38 return missing_packets_.empty() ? kNewPacketCompletingFrame : kNewPacket; | |
| 39 } | |
| 40 | |
| 41 bool FrameInfo::Complete() const { return missing_packets_.empty(); } | |
| 42 | |
| 43 void FrameInfo::GetMissingPackets(bool newest_frame, | |
| 44 PacketIdSet* missing_packets) const { | |
| 45 if (newest_frame) { | |
| 46 // Missing packets capped by max_received_packet_id_. | |
| 47 PacketIdSet::const_iterator it_after_last_received = | |
| 48 missing_packets_.lower_bound(max_received_packet_id_); | |
| 49 missing_packets->insert(missing_packets_.begin(), it_after_last_received); | |
| 50 } else { | |
| 51 missing_packets->insert(missing_packets_.begin(), missing_packets_.end()); | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 FrameIdMap::FrameIdMap() | |
| 56 : waiting_for_key_(true), | |
| 57 last_released_frame_(kStartFrameId), | |
| 58 newest_frame_id_(kStartFrameId) {} | |
| 59 | |
| 60 FrameIdMap::~FrameIdMap() {} | |
| 61 | |
| 62 PacketType FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header) { | |
| 63 uint32 frame_id = rtp_header.frame_id; | |
| 64 uint32 reference_frame_id; | |
| 65 reference_frame_id = rtp_header.reference_frame_id; | |
| 66 | |
| 67 if (rtp_header.is_key_frame && waiting_for_key_) { | |
| 68 last_released_frame_ = static_cast<uint32>(frame_id - 1); | |
| 69 waiting_for_key_ = false; | |
| 70 } | |
| 71 | |
| 72 VLOG(3) << "InsertPacket frame:" << frame_id | |
| 73 << " packet:" << static_cast<int>(rtp_header.packet_id) | |
| 74 << " max packet:" << static_cast<int>(rtp_header.max_packet_id); | |
| 75 | |
| 76 if (IsOlderFrameId(frame_id, last_released_frame_) && !waiting_for_key_) { | |
| 77 return kTooOldPacket; | |
| 78 } | |
| 79 | |
| 80 // Update the last received frame id. | |
| 81 if (IsNewerFrameId(frame_id, newest_frame_id_)) { | |
| 82 newest_frame_id_ = frame_id; | |
| 83 } | |
| 84 | |
| 85 // Does this packet belong to a new frame? | |
| 86 FrameMap::iterator it = frame_map_.find(frame_id); | |
| 87 PacketType packet_type; | |
| 88 if (it == frame_map_.end()) { | |
| 89 // New frame. | |
| 90 linked_ptr<FrameInfo> frame_info(new FrameInfo(frame_id, | |
| 91 reference_frame_id, | |
| 92 rtp_header.max_packet_id, | |
| 93 rtp_header.is_key_frame)); | |
| 94 std::pair<FrameMap::iterator, bool> retval = | |
| 95 frame_map_.insert(std::make_pair(frame_id, frame_info)); | |
| 96 | |
| 97 packet_type = retval.first->second->InsertPacket(rtp_header.packet_id); | |
| 98 } else { | |
| 99 // Insert packet to existing frame. | |
| 100 packet_type = it->second->InsertPacket(rtp_header.packet_id); | |
| 101 } | |
| 102 return packet_type; | |
| 103 } | |
| 104 | |
| 105 void FrameIdMap::RemoveOldFrames(uint32 frame_id) { | |
| 106 FrameMap::iterator it = frame_map_.begin(); | |
| 107 | |
| 108 while (it != frame_map_.end()) { | |
| 109 if (IsNewerFrameId(it->first, frame_id)) { | |
| 110 ++it; | |
| 111 } else { | |
| 112 // Older or equal; erase. | |
| 113 frame_map_.erase(it++); | |
| 114 } | |
| 115 } | |
| 116 last_released_frame_ = frame_id; | |
| 117 } | |
| 118 | |
| 119 void FrameIdMap::Clear() { | |
| 120 frame_map_.clear(); | |
| 121 waiting_for_key_ = true; | |
| 122 last_released_frame_ = kStartFrameId; | |
| 123 newest_frame_id_ = kStartFrameId; | |
| 124 } | |
| 125 | |
| 126 uint32 FrameIdMap::NewestFrameId() const { return newest_frame_id_; } | |
| 127 | |
| 128 bool FrameIdMap::NextContinuousFrame(uint32* frame_id) const { | |
| 129 FrameMap::const_iterator it; | |
| 130 | |
| 131 for (it = frame_map_.begin(); it != frame_map_.end(); ++it) { | |
| 132 if (it->second->Complete() && ContinuousFrame(it->second.get())) { | |
| 133 *frame_id = it->first; | |
| 134 return true; | |
| 135 } | |
| 136 } | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 bool FrameIdMap::HaveMultipleDecodableFrames() const { | |
| 141 // Find the oldest decodable frame. | |
| 142 FrameMap::const_iterator it; | |
| 143 bool found_one = false; | |
| 144 for (it = frame_map_.begin(); it != frame_map_.end(); ++it) { | |
| 145 if (it->second->Complete() && DecodableFrame(it->second.get())) { | |
| 146 if (found_one) { | |
| 147 return true; | |
| 148 } else { | |
| 149 found_one = true; | |
| 150 } | |
| 151 } | |
| 152 } | |
| 153 return false; | |
| 154 } | |
| 155 | |
| 156 uint32 FrameIdMap::LastContinuousFrame() const { | |
| 157 uint32 last_continuous_frame_id = last_released_frame_; | |
| 158 uint32 next_expected_frame = last_released_frame_; | |
| 159 | |
| 160 FrameMap::const_iterator it; | |
| 161 | |
| 162 do { | |
| 163 next_expected_frame++; | |
| 164 it = frame_map_.find(next_expected_frame); | |
| 165 if (it == frame_map_.end()) | |
| 166 break; | |
| 167 if (!it->second->Complete()) | |
| 168 break; | |
| 169 | |
| 170 // We found the next continuous frame. | |
| 171 last_continuous_frame_id = it->first; | |
| 172 } while (next_expected_frame != newest_frame_id_); | |
| 173 return last_continuous_frame_id; | |
| 174 } | |
| 175 | |
| 176 bool FrameIdMap::NextFrameAllowingSkippingFrames(uint32* frame_id) const { | |
| 177 // Find the oldest decodable frame. | |
| 178 FrameMap::const_iterator it_best_match = frame_map_.end(); | |
| 179 FrameMap::const_iterator it; | |
| 180 for (it = frame_map_.begin(); it != frame_map_.end(); ++it) { | |
| 181 if (it->second->Complete() && DecodableFrame(it->second.get())) { | |
| 182 if (it_best_match == frame_map_.end() || | |
| 183 IsOlderFrameId(it->first, it_best_match->first)) { | |
| 184 it_best_match = it; | |
| 185 } | |
| 186 } | |
| 187 } | |
| 188 if (it_best_match == frame_map_.end()) | |
| 189 return false; | |
| 190 | |
| 191 *frame_id = it_best_match->first; | |
| 192 return true; | |
| 193 } | |
| 194 | |
| 195 bool FrameIdMap::Empty() const { return frame_map_.empty(); } | |
| 196 | |
| 197 int FrameIdMap::NumberOfCompleteFrames() const { | |
| 198 int count = 0; | |
| 199 FrameMap::const_iterator it; | |
| 200 for (it = frame_map_.begin(); it != frame_map_.end(); ++it) { | |
| 201 if (it->second->Complete()) { | |
| 202 ++count; | |
| 203 } | |
| 204 } | |
| 205 return count; | |
| 206 } | |
| 207 | |
| 208 bool FrameIdMap::FrameExists(uint32 frame_id) const { | |
| 209 return frame_map_.end() != frame_map_.find(frame_id); | |
| 210 } | |
| 211 | |
| 212 void FrameIdMap::GetMissingPackets(uint32 frame_id, | |
| 213 bool last_frame, | |
| 214 PacketIdSet* missing_packets) const { | |
| 215 FrameMap::const_iterator it = frame_map_.find(frame_id); | |
| 216 if (it == frame_map_.end()) | |
| 217 return; | |
| 218 | |
| 219 it->second->GetMissingPackets(last_frame, missing_packets); | |
| 220 } | |
| 221 | |
| 222 bool FrameIdMap::ContinuousFrame(FrameInfo* frame) const { | |
| 223 DCHECK(frame); | |
| 224 if (waiting_for_key_ && !frame->is_key_frame()) | |
| 225 return false; | |
| 226 return static_cast<uint32>(last_released_frame_ + 1) == frame->frame_id(); | |
| 227 } | |
| 228 | |
| 229 bool FrameIdMap::DecodableFrame(FrameInfo* frame) const { | |
| 230 if (frame->is_key_frame()) | |
| 231 return true; | |
| 232 if (waiting_for_key_ && !frame->is_key_frame()) | |
| 233 return false; | |
| 234 // Self-reference? | |
| 235 if (frame->referenced_frame_id() == frame->frame_id()) | |
| 236 return true; | |
| 237 | |
| 238 // Current frame is not necessarily referencing the last frame. | |
| 239 // Do we have the reference frame? | |
| 240 if (IsOlderFrameId(frame->referenced_frame_id(), last_released_frame_)) { | |
| 241 return true; | |
| 242 } | |
| 243 return frame->referenced_frame_id() == last_released_frame_; | |
| 244 } | |
| 245 | |
| 246 } // namespace cast | |
| 247 } // namespace media | |
| OLD | NEW |