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