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 |